Django rest framework 簡易使用方法


Django rest framework 工具包做API非常方便。

下面簡單說一下幾個功能的實現方法。

實現功能為,匿名用戶訪問首頁一分鍾能訪問3次,登錄用戶一分鍾訪問6次,只有登錄用戶才能訪問order頁面。

第一步,注冊app

 

 1 INSTALLED_APPS = [
 2     'django.contrib.admin',
 3     'django.contrib.auth',
 4     'django.contrib.contenttypes',
 5     'django.contrib.sessions',
 6     'django.contrib.messages',
 7     'django.contrib.staticfiles',
 8     'app.apps.AppConfig',
 9     'rest_framework',  #注冊
10 ]

settings文件注冊app

 

 

第二步,定義URL,注意url路徑最好使用名詞。我們這里注冊三個視圖函數的url,實現驗證,首頁和定單頁面。

 

 1 from django.conf.urls import url
 2 from django.contrib import admin
 3 from app import views
 4 
 5 urlpatterns = [
 6     url(r'^admin/', admin.site.urls),
 7     url(r'^auth/', views.AuthView.as_view()),  #驗證
 8     url(r'^index/', views.IndexView.as_view()), #首頁
 9     url(r'^order/', views.OrderView.as_view()),  #定單
10 ] 

url文件設置路由

 

 

第三步,auth視圖函數

 

 1 from rest_framework.views import APIView
 2 from rest_framework.request import Request
 3 from django.http import JsonResponse,HttpResponse
 4 
 5 from app.utils.commons import gen_token
 6 from app.utils.auth import LuffyAuthentication
 7 from app.utils.throttle import LuffyAnonRateThrottle,LuffyUserRateThrottle
 8 from app.utils.permission import LuffyPermission
 9 from . import models
10 
11 class AuthView(APIView):
12 
13     """
14     認證相關視圖
15     由於繼承了APIView,所以csrf就沒有了,具體的源代碼只是有一個裝飾器,
16     加上了csrf_exempt裝飾器,屏蔽了csrf
17     寫法是在return的時候csrf_exempt(view) 和@使用裝飾器效果是一樣的,這種寫法還可以寫在url路由中。
18     """
19     def post(self,request,*args,**kwargs):
20         """
21         用戶登錄功能
22         :param request:
23         :param args:
24         :param kwargs:
25         :return:
26         """
27         ret = {'code': 1000, 'msg': None}
28         # 默認要返回的信息
29         user = request.data.get('username')
30         # 這里的request已經不是原來的request了
31         pwd = request.data.get('password')
32         user_obj = models.UserInfo.objects.filter(user=user, pwd=pwd).first()
33         if user_obj:
34             tk = gen_token(user)  #返回一個哈希過得字符串
35             #進行token驗證
36             models.Token.objects.update_or_create(user=user_obj, defaults={'token': tk})
37             # 數據庫存入一個token信息
38             ret['code'] = 1001
39             ret['token'] = tk
40         else:
41             ret['msg'] = "用戶名或密碼錯誤"
42         return JsonResponse(ret)

上面的代碼主要是實現了一個驗證的功能,通過gen_token函數來驗證,並存入數據庫信息。

gen_token單獨寫到一個utils目錄下的auth.py文件中。代碼如下:

1 def gen_token(username):
2     import time
3     import hashlib
4     ctime = str(time.time())
5     hash = hashlib.md5(username.encode('utf-8'))
6     hash.update(ctime.encode('utf-8'))
7     return hash.hexdigest()

通過時間和哈希等生成一個不重復的字符串。

 

第四步,index視圖函數

 1 class IndexView(APIView):
 2     """
 3     用戶認證
 4         http://127.0.0.1:8001/v1/index/?tk=sdfasdfasdfasdfasdfasdf
 5         獲取用戶傳入的Token
 6 
 7     首頁限制:request.user
 8         匿名:5/m
 9         用戶:10/m
10     """
11     authentication_classes = [LuffyAuthentication,]
12     #認證成功返回一個用戶名,一個對象,不成功就是None
13     throttle_classes = [LuffyAnonRateThrottle,LuffyUserRateThrottle]
14     #訪問次數限制,如果合格都為True
15     def get(self,request,*args,**kwargs):
16         return HttpResponse('首頁')

同樣,將LuffyAuthenticationLuffyAnonRateThrottle,LuffyUserRateThrottle寫到了utils目錄下。代碼如下:

auth.py :

 

 1 from rest_framework.authentication import BaseAuthentication
 2 from rest_framework import exceptions
 3 from app import models
 4 class LuffyAuthentication(BaseAuthentication):
 5     def authenticate(self, request):
 6         tk = request.query_params.get('tk')
 7         if not tk:
 8             return (None,None)
 9             # raise exceptions.AuthenticationFailed('認證失敗')
10 
11         token_obj = models.Token.objects.filter(token=tk).first()
12         if not token_obj:
13             return (None,None)
14 
15         return (token_obj.user,token_obj)

 

驗證是否為登錄用戶,如果之前沒有登陸過,則將token信息存到數據庫

 

throttle.py :

 1 from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
 2 
 3 
 4 class LuffyAnonRateThrottle(SimpleRateThrottle):
 5 
 6     scope = "luffy_anon"
 7 
 8     def allow_request(self, request, view):
 9         """
10         Return `True` if the request should be allowed, `False` otherwise.
11         """
12         if request.user:
13             return True
14 
15         # 獲取當前訪問用戶的唯一標識
16         self.key = self.get_cache_key(request, view)
17         # 根據當前用戶的唯一標識,獲取所有訪問記錄
18         # [1511312683.7824545, 1511312682.7824545, 1511312681.7824545]
19         self.history = self.cache.get(self.key, [])
20         # 獲取當前時間
21         self.now = self.timer()
22 
23         # Drop any requests from the history which have now passed the
24         # throttle duration
25         while self.history and self.history[-1] <= self.now - self.duration:
26             self.history.pop()
27         if len(self.history) >= self.num_requests:   #判斷訪問次數是否大於限制次數
28             return self.throttle_failure()
29         return self.throttle_success()  #返回True
30 
31     def get_cache_key(self, request, view):
32         return 'throttle_%(scope)s_%(ident)s' % {
33             'scope': self.scope,
34             'ident': self.get_ident(request),
35 
36             # 判斷是否為代理等等
37 
38         }
39 
40 class LuffyUserRateThrottle(SimpleRateThrottle):
41     scope = "luffy_user"
42     def allow_request(self, request, view):
43         """
44         Return `True` if the request should be allowed, `False` otherwise.
45         """
46         if not request.user:   #判斷登錄直接返回True
47             return True
48         # 獲取當前訪問用戶的唯一標識
49         # 用戶對所有頁面
50         # self.key = request.user.user
51 
52         self.key = request.user.user + view.__class__.__name__
53         # 用戶對單頁面的訪問限制
54 
55         # 根據當前用戶的唯一標識,獲取所有訪問記錄
56         # [1511312683.7824545, 1511312682.7824545, 1511312681.7824545]
57         self.history = self.cache.get(self.key, [])
58         # 獲取當前時間
59         self.now = self.timer()
60 
61         # Drop any requests from the history which have now passed the
62         # throttle duration
63         while self.history and self.history[-1] <= self.now - self.duration:
64             self.history.pop()
65         if len(self.history) >= self.num_requests:   #訪問次數的限制
66             return self.throttle_failure()
67         return self.throttle_success()   #返回True

限制匿名用戶和登錄用戶的訪問次數,需要從settings中的配置拿去配置信息。

permission.py

 1 from rest_framework.permissions import BasePermission
 2 
 3 
 4 class LuffyPermission(BasePermission):
 5     def has_permission(self, request, view):
 6         """
 7         Return `True` if permission is granted, `False` otherwise.
 8         """
 9         if request.user:
10             return True
11         return False

權限控制

第五步,order視圖函數

 1 class OrderView(APIView):
 2     """
 3     訂單頁面:只有登錄成功后才能訪問
 4         - 認證(匿名和用戶)
 5         - 權限(用戶)
 6         - 限制()
 7     """
 8     authentication_classes = [LuffyAuthentication, ]
 9     permission_classes = [LuffyPermission,] #登錄就返回True
10     throttle_classes = [LuffyAnonRateThrottle, LuffyUserRateThrottle]
11 
12     def get(self,request,*args,**kwargs):
13 
14         return HttpResponse('訂單')

 

第六步,settings配置

1 REST_FRAMEWORK = {
2     'UNAUTHENTICATED_USER': None,
3     'UNAUTHENTICATED_TOKEN': None,
4     "DEFAULT_THROTTLE_RATES": {
5         'luffy_anon': '3/m', #匿名用戶一分鍾訪問3次
6         'luffy_user': '6/m'  #登錄用戶一分鍾訪問6次
7     },
8 }

 

最后,實現功能為,匿名用戶訪問首頁一分鍾能訪問3次,登錄用戶一分鍾訪問6次,只有登錄用戶才能訪問order頁面。

學習Django rest framework需要隨時查看源代碼,判斷源代碼的邏輯思路來自定義自己的功能,如此學習效率極高。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM