200 OK - [GET]:服務器成功返回用戶請求的數據,該操做是冪等的(Idempotent)。 201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。 202 Accepted - [*]:表示一個請求已經進入後臺排隊(異步任務) 204 NO CONTENT - [DELETE]:用戶刪除數據成功。 400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操做,該操做是冪等的。 401 Unauthorized - [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤)。 403 Forbidden - [*] 表示用戶獲得受權(與401錯誤相對),可是訪問是被禁止的。 404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操做,該操做是冪等的。 406 Not Acceptable - [GET]:用戶請求的格式不可得(好比用戶請求JSON格式,可是隻有XML格式)。 410 Gone -[GET]:用戶請求的資源被永久刪除,且不會再獲得的。 422 Unprocesable entity - [POST/PUT/PATCH] 當建立一個對象時,發生一個驗證錯誤。 500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶將沒法判斷髮出的請求是否成功。 更多看這裏:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
{ error: "Invalid API key" }
GET /collection:返回資源對象的列表(數組) GET /collection/resource:返回單個資源對象 POST /collection:返回新生成的資源對象 PUT /collection/resource:返回完整的資源對象 PATCH /collection/resource:返回完整的資源對象 DELETE /collection/resource:返回一個空文檔
{"link": { "rel": "collection https://www.example.com/zoos", "href": "https://api.example.com/zoos", "title": "List of zoos", "type": "application/vnd.yourformat+json" }}
摘自:http://www.ruanyifeng.com/blog/2014/05/restful_api.html html
路由系統:python
urlpatterns = [ url(r'^users', Users.as_view()), ]
CBV視圖:web
from django.views import View from django.http import JsonResponse class Users(View): def get(self, request, *args, **kwargs): result = { 'status': True, 'data': 'response data' } return JsonResponse(result, status=200) def post(self, request, *args, **kwargs): result = { 'status': True, 'data': 'response data' } return JsonResponse(result, status=200)
url.py數據庫
from django.conf.urls import url, include from web.views.s1_api import TestView urlpatterns = [ url(r'^test/', TestView.as_view()), ]
views.pydjango
from rest_framework.views import APIView from rest_framework.response import Response class TestView(APIView): def dispatch(self, request, *args, **kwargs): """ 請求到來以後,都要執行dispatch方法,dispatch方法根據請求方式不一樣觸發 get/post/put等方法 注意:APIView中的dispatch方法有好多好多的功能 """ return super().dispatch(request, *args, **kwargs) def get(self, request, *args, **kwargs): return Response('GET請求,響應內容') def post(self, request, *args, **kwargs): return Response('POST請求,響應內容') def put(self, request, *args, **kwargs): return Response('PUT請求,響應內容')
上述是rest framework框架基本流程,重要的功能是在APIView的dispatch中觸發。json
一、用戶url傳入的token認證api
url.py跨域
from django.conf.urls import url, include from web.viewsimport TestView urlpatterns = [ url(r'^test/', TestView.as_view()), ]
1 from rest_framework.views import APIView 2 from rest_framework.response import Response 3 from rest_framework.authentication import BaseAuthentication 4 from rest_framework.request import Request 5 from rest_framework import exceptions 6 7 token_list = [ 8 'sfsfss123kuf3j123', 9 'asijnfowerkkf9812', 10 ] 11 12 13 class TestAuthentication(BaseAuthentication): 14 def authenticate(self, request): 15 """ 16 用戶認證,若是驗證成功後返回元組: (用戶,用戶Token) 17 :param request: 18 :return: 19 None,表示跳過該驗證; 20 若是跳過了全部認證,默認用戶和Token和使用配置文件進行設置 21 self._authenticator = None 22 if api_settings.UNAUTHENTICATED_USER: 23 self.user = api_settings.UNAUTHENTICATED_USER() 24 else: 25 self.user = None 26 27 if api_settings.UNAUTHENTICATED_TOKEN: 28 self.auth = api_settings.UNAUTHENTICATED_TOKEN() 29 else: 30 self.auth = None 31 (user,token)表示驗證經過並設置用戶名和Token; 32 AuthenticationFailed異常 33 """ 34 val = request.query_params.get('token') 35 if val not in token_list: 36 raise exceptions.AuthenticationFailed("用戶認證失敗") 37 38 return ('登陸用戶', '用戶token') 39 40 def authenticate_header(self, request): 41 """ 42 Return a string to be used as the value of the `WWW-Authenticate` 43 header in a `401 Unauthenticated` response, or `None` if the 44 authentication scheme should return `403 Permission Denied` responses. 45 """ 46 # 驗證失敗時,返回的響應頭WWW-Authenticate對應的值 47 pass 48 49 50 class TestView(APIView): 51 authentication_classes = [TestAuthentication, ] 52 permission_classes = [] 53 54 def get(self, request, *args, **kwargs): 55 print(request.user) 56 print(request.auth) 57 return Response('GET請求,響應內容') 58 59 def post(self, request, *args, **kwargs): 60 return Response('POST請求,響應內容') 61 62 def put(self, request, *args, **kwargs): 63 return Response('PUT請求,響應內容')
二、請求頭認證數組
1 from django.conf.urls import url, include 2 from web.viewsimport TestView 3 4 urlpatterns = [ 5 url(r'^test/', TestView.as_view()), 6 ]
1 from rest_framework.views import APIView 2 from rest_framework.response import Response 3 from rest_framework.authentication import BaseAuthentication 4 from rest_framework.request import Request 5 from rest_framework import exceptions 6 7 token_list = [ 8 'sfsfss123kuf3j123', 9 'asijnfowerkkf9812', 10 ] 11 12 13 class TestAuthentication(BaseAuthentication): 14 def authenticate(self, request): 15 """ 16 用戶認證,若是驗證成功後返回元組: (用戶,用戶Token) 17 :param request: 18 :return: 19 None,表示跳過該驗證; 20 若是跳過了全部認證,默認用戶和Token和使用配置文件進行設置 21 self._authenticator = None 22 if api_settings.UNAUTHENTICATED_USER: 23 self.user = api_settings.UNAUTHENTICATED_USER() 24 else: 25 self.user = None 26 27 if api_settings.UNAUTHENTICATED_TOKEN: 28 self.auth = api_settings.UNAUTHENTICATED_TOKEN() 29 else: 30 self.auth = None 31 (user,token)表示驗證經過並設置用戶名和Token; 32 AuthenticationFailed異常 33 """ 34 import base64 35 auth = request.META.get('HTTP_AUTHORIZATION', b'') 36 if auth: 37 auth = auth.encode('utf-8') 38 auth = auth.split() 39 if not auth or auth[0].lower() != b'basic': 40 raise exceptions.AuthenticationFailed('驗證失敗') 41 if len(auth) != 2: 42 raise exceptions.AuthenticationFailed('驗證失敗') 43 username, part, password = base64.b64decode(auth[1]).decode('utf-8').partition(':') 44 if username == 'alex' and password == '123': 45 return ('登陸用戶', '用戶token') 46 else: 47 raise exceptions.AuthenticationFailed('用戶名或密碼錯誤') 48 49 def authenticate_header(self, request): 50 """ 51 Return a string to be used as the value of the `WWW-Authenticate` 52 header in a `401 Unauthenticated` response, or `None` if the 53 authentication scheme should return `403 Permission Denied` responses. 54 """ 55 return 'Basic realm=api' 56 57 58 class TestView(APIView): 59 authentication_classes = [TestAuthentication, ] 60 permission_classes = [] 61 62 def get(self, request, *args, **kwargs): 63 print(request.user) 64 print(request.auth) 65 return Response('GET請求,響應內容') 66 67 def post(self, request, *args, **kwargs): 68 return Response('POST請求,響應內容') 69 70 def put(self, request, *args, **kwargs): 71 return Response('PUT請求,響應內容')
三、多個認證規則瀏覽器
1 from django.conf.urls import url, include 2 from web.views.s2_auth import TestView 3 4 urlpatterns = [ 5 url(r'^test/', TestView.as_view()), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.authentication import BaseAuthentication 6 from rest_framework.request import Request 7 from rest_framework import exceptions 8 9 token_list = [ 10 'sfsfss123kuf3j123', 11 'asijnfowerkkf9812', 12 ] 13 14 15 class Test1Authentication(BaseAuthentication): 16 def authenticate(self, request): 17 """ 18 用戶認證,若是驗證成功後返回元組: (用戶,用戶Token) 19 :param request: 20 :return: 21 None,表示跳過該驗證; 22 若是跳過了全部認證,默認用戶和Token和使用配置文件進行設置 23 self._authenticator = None 24 if api_settings.UNAUTHENTICATED_USER: 25 self.user = api_settings.UNAUTHENTICATED_USER() # 默認值爲:匿名用戶 26 else: 27 self.user = None 28 29 if api_settings.UNAUTHENTICATED_TOKEN: 30 self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默認值爲:None 31 else: 32 self.auth = None 33 (user,token)表示驗證經過並設置用戶名和Token; 34 AuthenticationFailed異常 35 """ 36 import base64 37 auth = request.META.get('HTTP_AUTHORIZATION', b'') 38 if auth: 39 auth = auth.encode('utf-8') 40 else: 41 return None 42 print(auth,'xxxx') 43 auth = auth.split() 44 if not auth or auth[0].lower() != b'basic': 45 raise exceptions.AuthenticationFailed('驗證失敗') 46 if len(auth) != 2: 47 raise exceptions.AuthenticationFailed('驗證失敗') 48 username, part, password = base64.b64decode(auth[1]).decode('utf-8').partition(':') 49 if username == 'alex' and password == '123': 50 return ('登陸用戶', '用戶token') 51 else: 52 raise exceptions.AuthenticationFailed('用戶名或密碼錯誤') 53 54 def authenticate_header(self, request): 55 """ 56 Return a string to be used as the value of the `WWW-Authenticate` 57 header in a `401 Unauthenticated` response, or `None` if the 58 authentication scheme should return `403 Permission Denied` responses. 59 """ 60 # return 'Basic realm=api' 61 pass 62 63 class Test2Authentication(BaseAuthentication): 64 def authenticate(self, request): 65 """ 66 用戶認證,若是驗證成功後返回元組: (用戶,用戶Token) 67 :param request: 68 :return: 69 None,表示跳過該驗證; 70 若是跳過了全部認證,默認用戶和Token和使用配置文件進行設置 71 self._authenticator = None 72 if api_settings.UNAUTHENTICATED_USER: 73 self.user = api_settings.UNAUTHENTICATED_USER() # 默認值爲:匿名用戶 74 else: 75 self.user = None 76 77 if api_settings.UNAUTHENTICATED_TOKEN: 78 self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默認值爲:None 79 else: 80 self.auth = None 81 (user,token)表示驗證經過並設置用戶名和Token; 82 AuthenticationFailed異常 83 """ 84 val = request.query_params.get('token') 85 if val not in token_list: 86 raise exceptions.AuthenticationFailed("用戶認證失敗") 87 88 return ('登陸用戶', '用戶token') 89 90 def authenticate_header(self, request): 91 """ 92 Return a string to be used as the value of the `WWW-Authenticate` 93 header in a `401 Unauthenticated` response, or `None` if the 94 authentication scheme should return `403 Permission Denied` responses. 95 """ 96 pass 97 98 99 class TestView(APIView): 100 authentication_classes = [Test1Authentication, Test2Authentication] 101 permission_classes = [] 102 103 def get(self, request, *args, **kwargs): 104 print(request.user) 105 print(request.auth) 106 return Response('GET請求,響應內容') 107 108 def post(self, request, *args, **kwargs): 109 return Response('POST請求,響應內容') 110 111 def put(self, request, *args, **kwargs): 112 return Response('PUT請求,響應內容')
四、認證和權限
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'^test/', TestView.as_view()), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.authentication import BaseAuthentication 6 from rest_framework.permissions import BasePermission 7 8 from rest_framework.request import Request 9 from rest_framework import exceptions 10 11 token_list = [ 12 'sfsfss123kuf3j123', 13 'asijnfowerkkf9812', 14 ] 15 16 17 class TestAuthentication(BaseAuthentication): 18 def authenticate(self, request): 19 """ 20 用戶認證,若是驗證成功後返回元組: (用戶,用戶Token) 21 :param request: 22 :return: 23 None,表示跳過該驗證; 24 若是跳過了全部認證,默認用戶和Token和使用配置文件進行設置 25 self._authenticator = None 26 if api_settings.UNAUTHENTICATED_USER: 27 self.user = api_settings.UNAUTHENTICATED_USER() # 默認值爲:匿名用戶 28 else: 29 self.user = None 30 31 if api_settings.UNAUTHENTICATED_TOKEN: 32 self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默認值爲:None 33 else: 34 self.auth = None 35 (user,token)表示驗證經過並設置用戶名和Token; 36 AuthenticationFailed異常 37 """ 38 val = request.query_params.get('token') 39 if val not in token_list: 40 raise exceptions.AuthenticationFailed("用戶認證失敗") 41 42 return ('登陸用戶', '用戶token') 43 44 def authenticate_header(self, request): 45 """ 46 Return a string to be used as the value of the `WWW-Authenticate` 47 header in a `401 Unauthenticated` response, or `None` if the 48 authentication scheme should return `403 Permission Denied` responses. 49 """ 50 pass 51 52 53 class TestPermission(BasePermission): 54 message = "權限驗證失敗" 55 56 def has_permission(self, request, view): 57 """ 58 判斷是否有權限訪問當前請求 59 Return `True` if permission is granted, `False` otherwise. 60 :param request: 61 :param view: 62 :return: True有權限;False無權限 63 """ 64 if request.user == "管理員": 65 return True 66 67 # GenericAPIView中get_object時調用 68 def has_object_permission(self, request, view, obj): 69 """ 70 視圖繼承GenericAPIView,並在其中使用get_object時獲取對象時,觸發單獨對象權限驗證 71 Return `True` if permission is granted, `False` otherwise. 72 :param request: 73 :param view: 74 :param obj: 75 :return: True有權限;False無權限 76 """ 77 if request.user == "管理員": 78 return True 79 80 81 class TestView(APIView): 82 # 認證的動做是由request.user觸發 83 authentication_classes = [TestAuthentication, ] 84 85 # 權限 86 # 循環執行全部的權限 87 permission_classes = [TestPermission, ] 88 89 def get(self, request, *args, **kwargs): 90 # self.dispatch 91 print(request.user) 92 print(request.auth) 93 return Response('GET請求,響應內容') 94 95 def post(self, request, *args, **kwargs): 96 return Response('POST請求,響應內容') 97 98 def put(self, request, *args, **kwargs): 99 return Response('PUT請求,響應內容')
五、全局使用
上述操做中均是對單獨視圖進行特殊配置,若是想要對全局進行配置,則須要再配置文件中寫入便可。
1 REST_FRAMEWORK = { 2 'UNAUTHENTICATED_USER': None, 3 'UNAUTHENTICATED_TOKEN': None, 4 "DEFAULT_AUTHENTICATION_CLASSES": [ 5 "web.utils.TestAuthentication", 6 ], 7 "DEFAULT_PERMISSION_CLASSES": [ 8 "web.utils.TestPermission", 9 ], 10 }
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'^test/', TestView.as_view()), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 6 class TestView(APIView): 7 8 def get(self, request, *args, **kwargs): 9 # self.dispatch 10 print(request.user) 11 print(request.auth) 12 return Response('GET請求,響應內容') 13 14 def post(self, request, *args, **kwargs): 15 return Response('POST請求,響應內容') 16 17 def put(self, request, *args, **kwargs): 18 return Response('PUT請求,響應內容')
一、基於用戶IP限制訪問頻率
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'^test/', TestView.as_view()), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import time 4 from rest_framework.views import APIView 5 from rest_framework.response import Response 6 7 from rest_framework import exceptions 8 from rest_framework.throttling import BaseThrottle 9 from rest_framework.settings import api_settings 10 11 # 保存訪問記錄 12 RECORD = { 13 '用戶IP': [12312139, 12312135, 12312133, ] 14 } 15 16 17 class TestThrottle(BaseThrottle): 18 ctime = time.time 19 20 def get_ident(self, request): 21 """ 22 根據用戶IP和代理IP,當作請求者的惟一IP 23 Identify the machine making the request by parsing HTTP_X_FORWARDED_FOR 24 if present and number of proxies is > 0. If not use all of 25 HTTP_X_FORWARDED_FOR if it is available, if not use REMOTE_ADDR. 26 """ 27 xff = request.META.get('HTTP_X_FORWARDED_FOR') 28 remote_addr = request.META.get('REMOTE_ADDR') 29 num_proxies = api_settings.NUM_PROXIES 30 31 if num_proxies is not None: 32 if num_proxies == 0 or xff is None: 33 return remote_addr 34 addrs = xff.split(',') 35 client_addr = addrs[-min(num_proxies, len(addrs))] 36 return client_addr.strip() 37 38 return ''.join(xff.split()) if xff else remote_addr 39 40 def allow_request(self, request, view): 41 """ 42 是否仍然在容許範圍內 43 Return `True` if the request should be allowed, `False` otherwise. 44 :param request: 45 :param view: 46 :return: True,表示能夠經過;False表示已超過限制,不容許訪問 47 """ 48 # 獲取用戶惟一標識(如:IP) 49 50 # 容許一分鐘訪問10次 51 num_request = 10 52 time_request = 60 53 54 now = self.ctime() 55 ident = self.get_ident(request) 56 self.ident = ident 57 if ident not in RECORD: 58 RECORD[ident] = [now, ] 59 return True 60 history = RECORD[ident] 61 while history and history[-1] <= now - time_request: 62 history.pop() 63 if len(history) < num_request: 64 history.insert(0, now) 65 return True 66 67 def wait(self): 68 """ 69 多少秒後能夠容許繼續訪問 70 Optionally, return a recommended number of seconds to wait before 71 the next request. 72 """ 73 last_time = RECORD[self.ident][0] 74 now = self.ctime() 75 return int(60 + last_time - now) 76 77 78 class TestView(APIView): 79 throttle_classes = [TestThrottle, ] 80 81 def get(self, request, *args, **kwargs): 82 # self.dispatch 83 print(request.user) 84 print(request.auth) 85 return Response('GET請求,響應內容') 86 87 def post(self, request, *args, **kwargs): 88 return Response('POST請求,響應內容') 89 90 def put(self, request, *args, **kwargs): 91 return Response('PUT請求,響應內容') 92 93 def throttled(self, request, wait): 94 """ 95 訪問次數被限制時,定製錯誤信息 96 """ 97 98 class Throttled(exceptions.Throttled): 99 default_detail = '請求被限制.' 100 extra_detail_singular = '請 {wait} 秒以後再重試.' 101 extra_detail_plural = '請 {wait} 秒以後再重試.' 102 103 raise Throttled(wait)
二、基於用戶IP顯示訪問頻率(利於Django緩存)
1 REST_FRAMEWORK = { 2 'DEFAULT_THROTTLE_RATES': { 3 'test_scope': '10/m', 4 }, 5 }
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'^test/', TestView.as_view()), 6 ]
三、view中限制請求頻率
1 REST_FRAMEWORK = { 2 'DEFAULT_THROTTLE_RATES': { 3 'xxxxxx': '10/m', 4 }, 5 }
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'^test/', TestView.as_view()), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 6 from rest_framework import exceptions 7 from rest_framework.throttling import ScopedRateThrottle 8 9 10 # 繼承 ScopedRateThrottle 11 class TestThrottle(ScopedRateThrottle): 12 13 def get_cache_key(self, request, view): 14 """ 15 Should return a unique cache-key which can be used for throttling. 16 Must be overridden. 17 18 May return `None` if the request should not be throttled. 19 """ 20 if not request.user: 21 ident = self.get_ident(request) 22 else: 23 ident = request.user 24 25 return self.cache_format % { 26 'scope': self.scope, 27 'ident': ident 28 } 29 30 31 class TestView(APIView): 32 throttle_classes = [TestThrottle, ] 33 34 # 在settings中獲取 xxxxxx 對應的頻率限制值 35 throttle_scope = "xxxxxx" 36 37 def get(self, request, *args, **kwargs): 38 # self.dispatch 39 print(request.user) 40 print(request.auth) 41 return Response('GET請求,響應內容') 42 43 def post(self, request, *args, **kwargs): 44 return Response('POST請求,響應內容') 45 46 def put(self, request, *args, **kwargs): 47 return Response('PUT請求,響應內容') 48 49 def throttled(self, request, wait): 50 """ 51 訪問次數被限制時,定製錯誤信息 52 """ 53 54 class Throttled(exceptions.Throttled): 55 default_detail = '請求被限制.' 56 extra_detail_singular = '請 {wait} 秒以後再重試.' 57 extra_detail_plural = '請 {wait} 秒以後再重試.' 58 59 raise Throttled(wait)
四、匿名時用IP限制+登陸時用Token限制
1 REST_FRAMEWORK = { 2 'UNAUTHENTICATED_USER': None, 3 'UNAUTHENTICATED_TOKEN': None, 4 'DEFAULT_THROTTLE_RATES': { 5 'luffy_anon': '10/m', 6 'luffy_user': '20/m', 7 }, 8 }
1 from django.conf.urls import url, include 2 from web.views.s3_throttling import TestView 3 4 urlpatterns = [ 5 url(r'^test/', TestView.as_view()), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 6 from rest_framework.throttling import SimpleRateThrottle 7 8 9 class LuffyAnonRateThrottle(SimpleRateThrottle): 10 """ 11 匿名用戶,根據IP進行限制 12 """ 13 scope = "luffy_anon" 14 15 def get_cache_key(self, request, view): 16 # 用戶已登陸,則跳過 匿名頻率限制 17 if request.user: 18 return None 19 20 return self.cache_format % { 21 'scope': self.scope, 22 'ident': self.get_ident(request) 23 } 24 25 26 class LuffyUserRateThrottle(SimpleRateThrottle): 27 """ 28 登陸用戶,根據用戶token限制 29 """ 30 scope = "luffy_user" 31 32 def get_ident(self, request): 33 """ 34 認證成功時:request.user是用戶對象;request.auth是token對象 35 :param request: 36 :return: 37 """ 38 # return request.auth.token 39 return "user_token" 40 41 def get_cache_key(self, request, view): 42 """ 43 獲取緩存key 44 :param request: 45 :param view: 46 :return: 47 """ 48 # 未登陸用戶,則跳過 Token限制 49 if not request.user: 50 return None 51 52 return self.cache_format % { 53 'scope': self.scope, 54 'ident': self.get_ident(request) 55 } 56 57 58 class TestView(APIView): 59 throttle_classes = [LuffyUserRateThrottle, LuffyAnonRateThrottle, ] 60 61 def get(self, request, *args, **kwargs): 62 # self.dispatch 63 print(request.user) 64 print(request.auth) 65 return Response('GET請求,響應內容') 66 67 def post(self, request, *args, **kwargs): 68 return Response('POST請求,響應內容') 69 70 def put(self, request, *args, **kwargs): 71 return Response('PUT請求,響應內容')
五、全局使用
1 REST_FRAMEWORK = { 2 'DEFAULT_THROTTLE_CLASSES': [ 3 'api.utils.throttles.throttles.LuffyAnonRateThrottle', 4 'api.utils.throttles.throttles.LuffyUserRateThrottle', 5 ], 6 'DEFAULT_THROTTLE_RATES': { 7 'anon': '10/day', 8 'user': '10/day', 9 'luffy_anon': '10/m', 10 'luffy_user': '20/m', 11 }, 12 }
一、基於url的get傳參方式
如:/users?version=v1
1 REST_FRAMEWORK = { 2 'DEFAULT_VERSION': 'v1', # 默認版本 3 'ALLOWED_VERSIONS': ['v1', 'v2'], # 容許的版本 4 'VERSION_PARAM': 'version' # URL中獲取值的key 5 }
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'^test/', TestView.as_view(),name='test'), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.versioning import QueryParameterVersioning 6 7 8 class TestView(APIView): 9 versioning_class = QueryParameterVersioning 10 11 def get(self, request, *args, **kwargs): 12 13 # 獲取版本 14 print(request.version) 15 # 獲取版本管理的類 16 print(request.versioning_scheme) 17 18 # 反向生成URL 19 reverse_url = request.versioning_scheme.reverse('test', request=request) 20 print(reverse_url) 21 22 return Response('GET請求,響應內容') 23 24 def post(self, request, *args, **kwargs): 25 return Response('POST請求,響應內容') 26 27 def put(self, request, *args, **kwargs): 28 return Response('PUT請求,響應內容')
二、基於url的正則方式
如:/v1/users/
1 REST_FRAMEWORK = { 2 'DEFAULT_VERSION': 'v1', # 默認版本 3 'ALLOWED_VERSIONS': ['v1', 'v2'], # 容許的版本 4 'VERSION_PARAM': 'version' # URL中獲取值的key 5 }
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'^(?P<version>[v1|v2]+)/test/', TestView.as_view(), name='test'), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.versioning import URLPathVersioning 6 7 8 class TestView(APIView): 9 versioning_class = URLPathVersioning 10 11 def get(self, request, *args, **kwargs): 12 # 獲取版本 13 print(request.version) 14 # 獲取版本管理的類 15 print(request.versioning_scheme) 16 17 # 反向生成URL 18 reverse_url = request.versioning_scheme.reverse('test', request=request) 19 print(reverse_url) 20 21 return Response('GET請求,響應內容') 22 23 def post(self, request, *args, **kwargs): 24 return Response('POST請求,響應內容') 25 26 def put(self, request, *args, **kwargs): 27 return Response('PUT請求,響應內容')
三、基於 accept 請求頭方式
如:Accept: application/json; version=1.0
1 REST_FRAMEWORK = { 2 'DEFAULT_VERSION': 'v1', # 默認版本 3 'ALLOWED_VERSIONS': ['v1', 'v2'], # 容許的版本 4 'VERSION_PARAM': 'version' # URL中獲取值的key 5 }
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'^test/', TestView.as_view(), name='test'), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.versioning import AcceptHeaderVersioning 6 7 8 class TestView(APIView): 9 versioning_class = AcceptHeaderVersioning 10 11 def get(self, request, *args, **kwargs): 12 # 獲取版本 HTTP_ACCEPT頭 13 print(request.version) 14 # 獲取版本管理的類 15 print(request.versioning_scheme) 16 # 反向生成URL 17 reverse_url = request.versioning_scheme.reverse('test', request=request) 18 print(reverse_url) 19 20 return Response('GET請求,響應內容') 21 22 def post(self, request, *args, **kwargs): 23 return Response('POST請求,響應內容') 24 25 def put(self, request, *args, **kwargs): 26 return Response('PUT請求,響應內容')
四、基於主機名方法
如:v1.example.com
1 ALLOWED_HOSTS = ['*'] 2 REST_FRAMEWORK = { 3 'DEFAULT_VERSION': 'v1', # 默認版本 4 'ALLOWED_VERSIONS': ['v1', 'v2'], # 容許的版本 5 'VERSION_PARAM': 'version' # URL中獲取值的key 6 }
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'^test/', TestView.as_view(), name='test'), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.versioning import HostNameVersioning 6 7 8 class TestView(APIView): 9 versioning_class = HostNameVersioning 10 11 def get(self, request, *args, **kwargs): 12 # 獲取版本 13 print(request.version) 14 # 獲取版本管理的類 15 print(request.versioning_scheme) 16 # 反向生成URL 17 reverse_url = request.versioning_scheme.reverse('test', request=request) 18 print(reverse_url) 19 20 return Response('GET請求,響應內容') 21 22 def post(self, request, *args, **kwargs): 23 return Response('POST請求,響應內容') 24 25 def put(self, request, *args, **kwargs): 26 return Response('PUT請求,響應內容')
五、基於django路由系統的namespace
如:example.com/v1/users/
1 REST_FRAMEWORK = { 2 'DEFAULT_VERSION': 'v1', # 默認版本 3 'ALLOWED_VERSIONS': ['v1', 'v2'], # 容許的版本 4 'VERSION_PARAM': 'version' # URL中獲取值的key 5 }
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'^v1/', ([ 6 url(r'test/', TestView.as_view(), name='test'), 7 ], None, 'v1')), 8 url(r'^v2/', ([ 9 url(r'test/', TestView.as_view(), name='test'), 10 ], None, 'v2')), 11 12 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.versioning import NamespaceVersioning 6 7 8 class TestView(APIView): 9 versioning_class = NamespaceVersioning 10 11 def get(self, request, *args, **kwargs): 12 # 獲取版本 13 print(request.version) 14 # 獲取版本管理的類 15 print(request.versioning_scheme) 16 # 反向生成URL 17 reverse_url = request.versioning_scheme.reverse('test', request=request) 18 print(reverse_url) 19 20 return Response('GET請求,響應內容') 21 22 def post(self, request, *args, **kwargs): 23 return Response('POST請求,響應內容') 24 25 def put(self, request, *args, **kwargs): 26 return Response('PUT請求,響應內容')
六、全局使用
1 REST_FRAMEWORK = { 2 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning", 3 'DEFAULT_VERSION': 'v1', 4 'ALLOWED_VERSIONS': ['v1', 'v2'], 5 'VERSION_PARAM': 'version' 6 }
根據請求頭 content-type 選擇對應的解析器就請求體內容進行處理。
一、僅處理請求頭content-type爲application/json的請求體
1 from django.conf.urls import url, include 2 from web.views.s5_parser import TestView 3 4 urlpatterns = [ 5 url(r'test/', TestView.as_view(), name='test'), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.request import Request 6 from rest_framework.parsers import JSONParser 7 8 9 class TestView(APIView): 10 parser_classes = [JSONParser, ] 11 12 def post(self, request, *args, **kwargs): 13 print(request.content_type) 14 15 # 獲取請求的值,並使用對應的JSONParser進行處理 16 print(request.data) 17 18 # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值 19 print(request.POST) 20 print(request.FILES) 21 22 return Response('POST請求,響應內容') 23 24 def put(self, request, *args, **kwargs): 25 return Response('PUT請求,響應內容')
二、僅處理請求頭content-type爲application/x-www-form-urlencoded 的請求體
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'test/', TestView.as_view(), name='test'), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.request import Request 6 from rest_framework.parsers import FormParser 7 8 9 class TestView(APIView): 10 parser_classes = [FormParser, ] 11 12 def post(self, request, *args, **kwargs): 13 print(request.content_type) 14 15 # 獲取請求的值,並使用對應的JSONParser進行處理 16 print(request.data) 17 18 # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值 19 print(request.POST) 20 print(request.FILES) 21 22 return Response('POST請求,響應內容') 23 24 def put(self, request, *args, **kwargs): 25 return Response('PUT請求,響應內容')
三、僅處理請求頭content-type爲multipart/form-data的請求體
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'test/', TestView.as_view(), name='test'), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.request import Request 6 from rest_framework.parsers import MultiPartParser 7 8 9 class TestView(APIView): 10 parser_classes = [MultiPartParser, ] 11 12 def post(self, request, *args, **kwargs): 13 print(request.content_type) 14 15 # 獲取請求的值,並使用對應的JSONParser進行處理 16 print(request.data) 17 # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值 18 print(request.POST) 19 print(request.FILES) 20 return Response('POST請求,響應內容') 21 22 def put(self, request, *args, **kwargs): 23 return Response('PUT請求,響應內容')
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <form action="http://127.0.0.1:8000/test/" method="post" enctype="multipart/form-data"> 9 <input type="text" name="user" /> 10 <input type="file" name="img"> 11 12 <input type="submit" value="提交"> 13 14 </form> 15 </body> 16 </html>
四、僅上傳文件
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'test/(?P<filename>[^/]+)', TestView.as_view(), name='test'), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.request import Request 6 from rest_framework.parsers import FileUploadParser 7 8 9 class TestView(APIView): 10 parser_classes = [FileUploadParser, ] 11 12 def post(self, request, filename, *args, **kwargs): 13 print(filename) 14 print(request.content_type) 15 16 # 獲取請求的值,並使用對應的JSONParser進行處理 17 print(request.data) 18 # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值 19 print(request.POST) 20 print(request.FILES) 21 return Response('POST請求,響應內容') 22 23 def put(self, request, *args, **kwargs): 24 return Response('PUT請求,響應內容')
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <form action="http://127.0.0.1:8000/test/f1.numbers" method="post" enctype="multipart/form-data"> 9 <input type="text" name="user" /> 10 <input type="file" name="img"> 11 12 <input type="submit" value="提交"> 13 14 </form> 15 </body> 16 </html> 17 複製代碼
五、同時多個Parser
當同時使用多個parser時,rest framework會根據請求頭content-type自動進行比對,並使用對應parser
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'test/', TestView.as_view(), name='test'), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework.request import Request 6 from rest_framework.parsers import JSONParser, FormParser, MultiPartParser 7 8 9 class TestView(APIView): 10 parser_classes = [JSONParser, FormParser, MultiPartParser, ] 11 12 def post(self, request, *args, **kwargs): 13 print(request.content_type) 14 15 # 獲取請求的值,並使用對應的JSONParser進行處理 16 print(request.data) 17 # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值 18 print(request.POST) 19 print(request.FILES) 20 return Response('POST請求,響應內容') 21 22 def put(self, request, *args, **kwargs): 23 return Response('PUT請求,響應內容')
六、全局使用
1 REST_FRAMEWORK = { 2 'DEFAULT_PARSER_CLASSES':[ 3 'rest_framework.parsers.JSONParser' 4 'rest_framework.parsers.FormParser' 5 'rest_framework.parsers.MultiPartParser' 6 ] 7 8 }
1 from django.conf.urls import url, include 2 from web.views import TestView 3 4 urlpatterns = [ 5 url(r'test/', TestView.as_view(), name='test'), 6 ]
1 from rest_framework.views import APIView 2 from rest_framework.response import Response 3 4 5 class TestView(APIView): 6 def post(self, request, *args, **kwargs): 7 print(request.content_type) 8 9 # 獲取請求的值,並使用對應的JSONParser進行處理 10 print(request.data) 11 # application/x-www-form-urlencoded 或 multipart/form-data時,request.POST中才有值 12 print(request.POST) 13 print(request.FILES) 14 return Response('POST請求,響應內容') 15 16 def put(self, request, *args, **kwargs): 17 return Response('PUT請求,響應內容')
注意:個別特殊的值能夠經過Django的request對象 request._request 來進行獲取
序列化用於對用戶請求數據進行驗證和數據進行序列化。
一、自定義字段
1 from django.conf.urls import url, include 2 from web.views.s6_serializers import TestView 3 4 urlpatterns = [ 5 url(r'test/', TestView.as_view(), name='test'), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework import serializers 6 from .. import models 7 8 9 class PasswordValidator(object): 10 def __init__(self, base): 11 self.base = base 12 13 def __call__(self, value): 14 if value != self.base: 15 message = 'This field must be %s.' % self.base 16 raise serializers.ValidationError(message) 17 18 def set_context(self, serializer_field): 19 """ 20 This hook is called by the serializer instance, 21 prior to the validation call being made. 22 """ 23 # 執行驗證以前調用,serializer_fields是當前字段對象 24 pass 25 26 27 class UserSerializer(serializers.Serializer): 28 ut_title = serializers.CharField(source='ut.title') 29 user = serializers.CharField(min_length=6) 30 pwd = serializers.CharField(error_messages={'required': '密碼不能爲空'}, validators=[PasswordValidator('666')]) 31 32 33 class TestView(APIView): 34 def get(self, request, *args, **kwargs): 35 36 # 序列化,將數據庫查詢字段序列化爲字典 37 data_list = models.UserInfo.objects.all() 38 ser = UserSerializer(instance=data_list, many=True) 39 # 或 40 # obj = models.UserInfo.objects.all().first() 41 # ser = UserSerializer(instance=obj, many=False) 42 return Response(ser.data) 43 44 def post(self, request, *args, **kwargs): 45 # 驗證,對請求發來的數據進行驗證 46 ser = UserSerializer(data=request.data) 47 if ser.is_valid(): 48 print(ser.validated_data) 49 else: 50 print(ser.errors) 51 52 return Response('POST請求,響應內容')
二、基於Model自動生成字段
1 from django.conf.urls import url, include 2 from web.views.s6_serializers import TestView 3 4 urlpatterns = [ 5 url(r'test/', TestView.as_view(), name='test'), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework import serializers 6 from .. import models 7 8 9 class PasswordValidator(object): 10 def __init__(self, base): 11 self.base = str(base) 12 13 def __call__(self, value): 14 if value != self.base: 15 message = 'This field must be %s.' % self.base 16 raise serializers.ValidationError(message) 17 18 def set_context(self, serializer_field): 19 """ 20 This hook is called by the serializer instance, 21 prior to the validation call being made. 22 """ 23 # 執行驗證以前調用,serializer_fields是當前字段對象 24 pass 25 26 class ModelUserSerializer(serializers.ModelSerializer): 27 28 user = serializers.CharField(max_length=32) 29 30 class Meta: 31 model = models.UserInfo 32 fields = "__all__" 33 # fields = ['user', 'pwd', 'ut'] 34 depth = 2 35 extra_kwargs = {'user': {'min_length': 6}, 'pwd': {'validators': [PasswordValidator(666), ]}} 36 # read_only_fields = ['user'] 37 38 39 class TestView(APIView): 40 def get(self, request, *args, **kwargs): 41 42 # 序列化,將數據庫查詢字段序列化爲字典 43 data_list = models.UserInfo.objects.all() 44 ser = ModelUserSerializer(instance=data_list, many=True) 45 # 或 46 # obj = models.UserInfo.objects.all().first() 47 # ser = UserSerializer(instance=obj, many=False) 48 return Response(ser.data) 49 50 def post(self, request, *args, **kwargs): 51 # 驗證,對請求發來的數據進行驗證 52 print(request.data) 53 ser = ModelUserSerializer(data=request.data) 54 if ser.is_valid(): 55 print(ser.validated_data) 56 else: 57 print(ser.errors) 58 59 return Response('POST請求,響應內容')
三、生成URL
1 from django.conf.urls import url, include 2 from web.views.s6_serializers import TestView 3 4 urlpatterns = [ 5 url(r'test/', TestView.as_view(), name='test'), 6 url(r'detail/(?P<pk>\d+)/', TestView.as_view(), name='detail'), 7 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework import serializers 6 from .. import models 7 8 9 class PasswordValidator(object): 10 def __init__(self, base): 11 self.base = str(base) 12 13 def __call__(self, value): 14 if value != self.base: 15 message = 'This field must be %s.' % self.base 16 raise serializers.ValidationError(message) 17 18 def set_context(self, serializer_field): 19 """ 20 This hook is called by the serializer instance, 21 prior to the validation call being made. 22 """ 23 # 執行驗證以前調用,serializer_fields是當前字段對象 24 pass 25 26 27 class ModelUserSerializer(serializers.ModelSerializer): 28 ut = serializers.HyperlinkedIdentityField(view_name='detail') 29 class Meta: 30 model = models.UserInfo 31 fields = "__all__" 32 33 extra_kwargs = { 34 'user': {'min_length': 6}, 35 'pwd': {'validators': [PasswordValidator(666),]}, 36 } 37 38 39 40 class TestView(APIView): 41 def get(self, request, *args, **kwargs): 42 43 # 序列化,將數據庫查詢字段序列化爲字典 44 data_list = models.UserInfo.objects.all() 45 ser = ModelUserSerializer(instance=data_list, many=True, context={'request': request}) 46 # 或 47 # obj = models.UserInfo.objects.all().first() 48 # ser = UserSerializer(instance=obj, many=False) 49 return Response(ser.data) 50 51 def post(self, request, *args, **kwargs): 52 # 驗證,對請求發來的數據進行驗證 53 print(request.data) 54 ser = ModelUserSerializer(data=request.data) 55 if ser.is_valid(): 56 print(ser.validated_data) 57 else: 58 print(ser.errors) 59 60 return Response('POST請求,響應內容')
四、自動生成URL
1 from django.conf.urls import url, include 2 from web.views.s6_serializers import TestView 3 4 urlpatterns = [ 5 url(r'test/', TestView.as_view(), name='test'), 6 url(r'detail/(?P<pk>\d+)/', TestView.as_view(), name='xxxx'), 7 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework import serializers 6 from .. import models 7 8 9 class PasswordValidator(object): 10 def __init__(self, base): 11 self.base = str(base) 12 13 def __call__(self, value): 14 if value != self.base: 15 message = 'This field must be %s.' % self.base 16 raise serializers.ValidationError(message) 17 18 def set_context(self, serializer_field): 19 """ 20 This hook is called by the serializer instance, 21 prior to the validation call being made. 22 """ 23 # 執行驗證以前調用,serializer_fields是當前字段對象 24 pass 25 26 27 class ModelUserSerializer(serializers.HyperlinkedModelSerializer): 28 ll = serializers.HyperlinkedIdentityField(view_name='xxxx') 29 tt = serializers.CharField(required=False) 30 31 class Meta: 32 model = models.UserInfo 33 fields = "__all__" 34 list_serializer_class = serializers.ListSerializer 35 36 extra_kwargs = { 37 'user': {'min_length': 6}, 38 'pwd': {'validators': [PasswordValidator(666), ]}, 39 'url': {'view_name': 'xxxx'}, 40 'ut': {'view_name': 'xxxx'}, 41 } 42 43 44 class TestView(APIView): 45 def get(self, request, *args, **kwargs): 46 # # 序列化,將數據庫查詢字段序列化爲字典 47 data_list = models.UserInfo.objects.all() 48 ser = ModelUserSerializer(instance=data_list, many=True, context={'request': request}) 49 # # 若是Many=True 50 # # 或 51 # # obj = models.UserInfo.objects.all().first() 52 # # ser = UserSerializer(instance=obj, many=False) 53 return Response(ser.data) 54 55 def post(self, request, *args, **kwargs): 56 # 驗證,對請求發來的數據進行驗證 57 print(request.data) 58 ser = ModelUserSerializer(data=request.data) 59 if ser.is_valid(): 60 print(ser.validated_data) 61 else: 62 print(ser.errors) 63 64 return Response('POST請求,響應內容')
一、根據頁碼進行分頁
1 from django.conf.urls import url, include 2 from rest_framework import routers 3 from web.views import s9_pagination 4 5 urlpatterns = [ 6 url(r'^test/', s9_pagination.UserViewSet.as_view()), 7 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework import serializers 5 from .. import models 6 7 from rest_framework.pagination import PageNumberPagination 8 9 10 class StandardResultsSetPagination(PageNumberPagination): 11 # 默認每頁顯示的數據條數 12 page_size = 1 13 # 獲取URL參數中設置的每頁顯示數據條數 14 page_size_query_param = 'page_size' 15 16 # 獲取URL參數中傳入的頁碼key 17 page_query_param = 'page' 18 19 # 最大支持的每頁顯示的數據條數 20 max_page_size = 1 21 22 23 class UserSerializer(serializers.ModelSerializer): 24 class Meta: 25 model = models.UserInfo 26 fields = "__all__" 27 28 29 class UserViewSet(APIView): 30 def get(self, request, *args, **kwargs): 31 user_list = models.UserInfo.objects.all().order_by('-id') 32 33 # 實例化分頁對象,獲取數據庫中的分頁數據 34 paginator = StandardResultsSetPagination() 35 page_user_list = paginator.paginate_queryset(user_list, self.request, view=self) 36 37 # 序列化對象 38 serializer = UserSerializer(page_user_list, many=True) 39 40 # 生成分頁和數據 41 response = paginator.get_paginated_response(serializer.data) 42 return response
二、位置和個數進行分頁
1 from django.conf.urls import url, include 2 from web.views import s9_pagination 3 4 urlpatterns = [ 5 url(r'^test/', s9_pagination.UserViewSet.as_view()), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework import serializers 5 from .. import models 6 7 from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination 8 9 10 class StandardResultsSetPagination(LimitOffsetPagination): 11 # 默認每頁顯示的數據條數 12 default_limit = 10 13 # URL中傳入的顯示數據條數的參數 14 limit_query_param = 'limit' 15 # URL中傳入的數據位置的參數 16 offset_query_param = 'offset' 17 # 最大每頁顯得條數 18 max_limit = None 19 20 class UserSerializer(serializers.ModelSerializer): 21 class Meta: 22 model = models.UserInfo 23 fields = "__all__" 24 25 26 class UserViewSet(APIView): 27 def get(self, request, *args, **kwargs): 28 user_list = models.UserInfo.objects.all().order_by('-id') 29 30 # 實例化分頁對象,獲取數據庫中的分頁數據 31 paginator = StandardResultsSetPagination() 32 page_user_list = paginator.paginate_queryset(user_list, self.request, view=self) 33 34 # 序列化對象 35 serializer = UserSerializer(page_user_list, many=True) 36 37 # 生成分頁和數據 38 response = paginator.get_paginated_response(serializer.data) 39 return response
三、遊標分頁
1 from django.conf.urls import url, include 2 from web.views import s9_pagination 3 4 urlpatterns = [ 5 url(r'^test/', s9_pagination.UserViewSet.as_view()), 6 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework import serializers 5 from .. import models 6 7 from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination 8 9 10 class StandardResultsSetPagination(CursorPagination): 11 # URL傳入的遊標參數 12 cursor_query_param = 'cursor' 13 # 默認每頁顯示的數據條數 14 page_size = 2 15 # URL傳入的每頁顯示條數的參數 16 page_size_query_param = 'page_size' 17 # 每頁顯示數據最大條數 18 max_page_size = 1000 19 20 # 根據ID從大到小排列 21 ordering = "id" 22 23 24 25 class UserSerializer(serializers.ModelSerializer): 26 class Meta: 27 model = models.UserInfo 28 fields = "__all__" 29 30 31 class UserViewSet(APIView): 32 def get(self, request, *args, **kwargs): 33 user_list = models.UserInfo.objects.all().order_by('-id') 34 35 # 實例化分頁對象,獲取數據庫中的分頁數據 36 paginator = StandardResultsSetPagination() 37 page_user_list = paginator.paginate_queryset(user_list, self.request, view=self) 38 39 # 序列化對象 40 serializer = UserSerializer(page_user_list, many=True) 41 42 # 生成分頁和數據 43 response = paginator.get_paginated_response(serializer.data) 44 return response
一、自定義路由
1 from django.conf.urls import url, include 2 from web.views import s11_render 3 4 urlpatterns = [ 5 url(r'^test/$', s11_render.TestView.as_view()), 6 url(r'^test\.(?P<format>[a-z0-9]+)$', s11_render.TestView.as_view()), 7 url(r'^test/(?P<pk>[^/.]+)/$', s11_render.TestView.as_view()), 8 url(r'^test/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)$', s11_render.TestView.as_view()) 9 ]
1 from rest_framework.views import APIView 2 from rest_framework.response import Response 3 from .. import models 4 5 6 class TestView(APIView): 7 def get(self, request, *args, **kwargs): 8 print(kwargs) 9 print(self.renderer_classes) 10 return Response('...')
二、半自動路由
1 from django.conf.urls import url, include 2 from web.views import s10_generic 3 4 urlpatterns = [ 5 url(r'^test/$', s10_generic.UserViewSet.as_view({'get': 'list', 'post': 'create'})), 6 url(r'^test/(?P<pk>\d+)/$', s10_generic.UserViewSet.as_view( 7 {'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})), 8 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.viewsets import ModelViewSet 4 from rest_framework import serializers 5 from .. import models 6 7 8 class UserSerializer(serializers.ModelSerializer): 9 class Meta: 10 model = models.UserInfo 11 fields = "__all__" 12 13 14 class UserViewSet(ModelViewSet): 15 queryset = models.UserInfo.objects.all() 16 serializer_class = UserSerializer
三、全自動路由
1 from django.conf.urls import url, include 2 from rest_framework import routers 3 from web.views import s10_generic 4 5 6 router = routers.DefaultRouter() 7 router.register(r'users', s10_generic.UserViewSet) 8 9 urlpatterns = [ 10 url(r'^', include(router.urls)), 11 ]
1 from rest_framework.viewsets import ModelViewSet 2 from rest_framework import serializers 3 from .. import models 4 5 6 class UserSerializer(serializers.ModelSerializer): 7 class Meta: 8 model = models.UserInfo 9 fields = "__all__" 10 11 12 class UserViewSet(ModelViewSet): 13 queryset = models.UserInfo.objects.all() 14 serializer_class = UserSerializer
一、GenericViewSet
1 from django.conf.urls import url, include 2 from web.views.s7_viewset import TestView 3 4 urlpatterns = [ 5 url(r'test/', TestView.as_view({'get':'list'}), name='test'), 6 url(r'detail/(?P<pk>\d+)/', TestView.as_view({'get':'list'}), name='xxxx'), 7 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework import viewsets 4 from rest_framework.response import Response 5 6 7 class TestView(viewsets.GenericViewSet): 8 def list(self, request, *args, **kwargs): 9 return Response('...') 10 11 def add(self, request, *args, **kwargs): 12 pass 13 14 def delete(self, request, *args, **kwargs): 15 pass 16 17 def edit(self, request, *args, **kwargs): 18 pass
二、ModelViewSet(自定義URL)
1 from django.conf.urls import url, include 2 from web.views import s10_generic 3 4 urlpatterns = [ 5 url(r'^test/$', s10_generic.UserViewSet.as_view({'get': 'list', 'post': 'create'})), 6 url(r'^test/(?P<pk>\d+)/$', s10_generic.UserViewSet.as_view( 7 {'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})), 8 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.viewsets import ModelViewSet 4 from rest_framework import serializers 5 from .. import models 6 7 8 class UserSerializer(serializers.ModelSerializer): 9 class Meta: 10 model = models.UserInfo 11 fields = "__all__" 12 13 14 class UserViewSet(ModelViewSet): 15 queryset = models.UserInfo.objects.all() 16 serializer_class = UserSerializer
三、ModelViewSet(rest framework路由)
1 from django.conf.urls import url, include 2 from rest_framework import routers 3 from app01 import views 4 5 router = routers.DefaultRouter() 6 router.register(r'users', views.UserViewSet) 7 router.register(r'groups', views.GroupViewSet) 8 9 # Wire up our API using automatic URL routing. 10 # Additionally, we include login URLs for the browsable API. 11 urlpatterns = [ 12 url(r'^', include(router.urls)), 13 ]
1 from rest_framework import viewsets 2 from rest_framework import serializers 3 4 5 class UserSerializer(serializers.HyperlinkedModelSerializer): 6 class Meta: 7 model = models.User 8 fields = ('url', 'username', 'email', 'groups') 9 10 11 class GroupSerializer(serializers.HyperlinkedModelSerializer): 12 class Meta: 13 model = models.Group 14 fields = ('url', 'name') 15 16 class UserViewSet(viewsets.ModelViewSet): 17 """ 18 API endpoint that allows users to be viewed or edited. 19 """ 20 queryset = User.objects.all().order_by('-date_joined') 21 serializer_class = UserSerializer 22 23 24 class GroupViewSet(viewsets.ModelViewSet): 25 """ 26 API endpoint that allows groups to be viewed or edited. 27 """ 28 queryset = Group.objects.all() 29 serializer_class = GroupSerializer
根據 用戶請求URL 或 用戶可接受的類型,篩選出合適的 渲染組件。
用戶請求URL:
用戶請求頭:
一、json
訪問URL:
1 from django.conf.urls import url, include 2 from web.views import s11_render 3 4 urlpatterns = [ 5 url(r'^test/$', s11_render.TestView.as_view()), 6 url(r'^test\.(?P<format>[a-z0-9]+)', s11_render.TestView.as_view()), 7 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework import serializers 6 7 from rest_framework.renderers import JSONRenderer 8 9 from .. import models 10 11 12 class TestSerializer(serializers.ModelSerializer): 13 class Meta: 14 model = models.UserInfo 15 fields = "__all__" 16 17 18 class TestView(APIView): 19 renderer_classes = [JSONRenderer, ] 20 21 def get(self, request, *args, **kwargs): 22 user_list = models.UserInfo.objects.all() 23 ser = TestSerializer(instance=user_list, many=True) 24 return Response(ser.data)
二、 表格
訪問URL:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework import serializers 6 7 from rest_framework.renderers import AdminRenderer 8 9 from .. import models 10 11 12 class TestSerializer(serializers.ModelSerializer): 13 class Meta: 14 model = models.UserInfo 15 fields = "__all__" 16 17 18 class TestView(APIView): 19 renderer_classes = [AdminRenderer, ] 20 21 def get(self, request, *args, **kwargs): 22 user_list = models.UserInfo.objects.all() 23 ser = TestSerializer(instance=user_list, many=True) 24 return Response(ser.data)
三、 Form表單
訪問URL:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework import serializers 6 7 from rest_framework.renderers import JSONRenderer 8 from rest_framework.renderers import AdminRenderer 9 from rest_framework.renderers import HTMLFormRenderer 10 11 from .. import models 12 13 14 class TestSerializer(serializers.ModelSerializer): 15 class Meta: 16 model = models.UserInfo 17 fields = "__all__" 18 19 20 class TestView(APIView): 21 renderer_classes = [HTMLFormRenderer, ] 22 23 def get(self, request, *args, **kwargs): 24 user_list = models.UserInfo.objects.all().first() 25 ser = TestSerializer(instance=user_list, many=False) 26 return Response(ser.data)
四、自定義顯示模板
訪問URL:
1 from django.conf.urls import url, include 2 from web.views import s11_render 3 4 urlpatterns = [ 5 url(r'^test/$', s11_render.TestView.as_view()), 6 url(r'^test\.(?P<format>[a-z0-9]+)', s11_render.TestView.as_view()), 7 ]
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework import serializers 6 from rest_framework.renderers import TemplateHTMLRenderer 7 8 from .. import models 9 10 11 class TestSerializer(serializers.ModelSerializer): 12 class Meta: 13 model = models.UserInfo 14 fields = "__all__" 15 16 17 class TestView(APIView): 18 renderer_classes = [TemplateHTMLRenderer, ] 19 20 def get(self, request, *args, **kwargs): 21 user_list = models.UserInfo.objects.all().first() 22 ser = TestSerializer(instance=user_list, many=False) 23 return Response(ser.data, template_name='user_detail.html')
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 {{ user }} 9 {{ pwd }} 10 {{ ut }} 11 </body> 12 </html>
五、 瀏覽器格式API+JSON
訪問URL:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from rest_framework.views import APIView 4 from rest_framework.response import Response 5 from rest_framework import serializers 6 7 from rest_framework.renderers import JSONRenderer 8 from rest_framework.renderers import BrowsableAPIRenderer 9 10 from .. import models 11 12 13 class TestSerializer(serializers.ModelSerializer): 14 class Meta: 15 model = models.UserInfo 16 fields = "__all__" 17 18 19 class CustomBrowsableAPIRenderer(BrowsableAPIRenderer): 20 def get_default_renderer(self, view): 21 return JSONRenderer() 22 23 24 class TestView(APIView): 25 renderer_classes = [CustomBrowsableAPIRenderer, ] 26 27 def get(self, request, *args, **kwargs): 28 user_list = models.UserInfo.objects.all().first() 29 ser = TestSerializer(instance=user_list, many=False) 30 return Response(ser.data, template_name='user_detail.html')
注意:若是同時多個存在時,自動根據URL後綴來選擇渲染器。