''' 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 '''
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"
}}
1 urlpatterns = [ 2 url(r'^users/$', views.Users.as_view()), 3 url(r'^users2/$', views.user2), 4 5 ]
1 import json 2 3 def user2(request): 4 if request.method=='GET': 5 dic = {'status':200,'name': 'lqz2', 'age': 18} 6 return HttpResponse(json.dumps(dic)) 7 elif request.method=='POST': 8 dic = {'status': 200, 'msg': '修改爲功'} 9 return JsonResponse(dic) 10 11 class Users(View): 12 def get(self, request): 13 dic = {'status':200,'name': 'lqz', 'age': 18} 14 return HttpResponse(json.dumps(dic)) 15 16 def post(self, request): 17 dic = {'status': 200, 'msg': '修改爲功'} 18 return JsonResponse(dic)
1 @classmethod 2 def as_view(cls, **initkwargs): 3 """ 4 Store the original class on the view function. 5 6 This allows us to discover information about the view when we do URL 7 reverse lookups. Used for breadcrumb generation. 8 """ 9 if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet): 10 def force_evaluation(): 11 raise RuntimeError( 12 'Do not evaluate the `.queryset` attribute directly, ' 13 'as the result will be cached and reused between requests. ' 14 'Use `.all()` or call `.get_queryset()` instead.' 15 ) 16 cls.queryset._fetch_all = force_evaluation 17 18 view = super(APIView, cls).as_view(**initkwargs) 19 view.cls = cls 20 view.initkwargs = initkwargs 21 22 # Note: session based authentication is explicitly CSRF validated, 23 # all other authentication is CSRF exempt. 24 return csrf_exempt(view)
1 def dispatch(self, request, *args, **kwargs): 2 """ 3 `.dispatch()` is pretty much the same as Django's regular dispatch, 4 but with extra hooks for startup, finalize, and exception handling. 5 """ 6 self.args = args 7 self.kwargs = kwargs 8 request = self.initialize_request(request, *args, **kwargs) 9 self.request = request 10 self.headers = self.default_response_headers # deprecate? 11 12 try: 13 self.initial(request, *args, **kwargs) 14 15 # Get the appropriate handler method 16 if request.method.lower() in self.http_method_names: 17 handler = getattr(self, request.method.lower(), 18 self.http_method_not_allowed) 19 else: 20 handler = self.http_method_not_allowed 21 22 response = handler(request, *args, **kwargs) 23 24 except Exception as exc: 25 response = self.handle_exception(exc) 26 27 self.response = self.finalize_response(request, response, *args, **kwargs) 28 return self.response
def initialize_request(self, request, *args, **kwargs): """ Returns the initial request object. """ parser_context = self.get_parser_context(request) return Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context )
1 def initial(self, request, *args, **kwargs): 2 """ 3 Runs anything that needs to occur prior to calling the method handler. 4 """ 5 self.format_kwarg = self.get_format_suffix(**kwargs) 6 7 # Perform content negotiation and store the accepted info on the request 8 neg = self.perform_content_negotiation(request) 9 request.accepted_renderer, request.accepted_media_type = neg 10 11 # Determine the API version, if versioning is in use. 12 version, scheme = self.determine_version(request, *args, **kwargs) 13 request.version, request.versioning_scheme = version, scheme 14 15 # Ensure that the incoming request is permitted 16 self.perform_authentication(request) 17 self.check_permissions(request) 18 self.check_throttles(request)
1 from django.db import models 2 3 # Create your models here. 4 5 6 class Book(models.Model): 7 title=models.CharField(max_length=32) 8 price=models.IntegerField() 9 pub_date=models.DateField() 10 publish=models.ForeignKey("Publish") 11 authors=models.ManyToManyField("Author") 12 def __str__(self): 13 return self.title 14 15 class Publish(models.Model): 16 name=models.CharField(max_length=32) 17 email=models.EmailField() 18 def __str__(self): 19 return self.name 20 21 class Author(models.Model): 22 name=models.CharField(max_length=32) 23 age=models.IntegerField() 24 def __str__(self): 25 return self.name
1 from rest_framework.views import APIView 2 from rest_framework.response import Response 3 from .models import * 4 from django.shortcuts import HttpResponse 5 from django.core import serializers 6 7 8 from rest_framework import serializers 9 10 class BookSerializers(serializers.Serializer): 11 title=serializers.CharField(max_length=32) 12 price=serializers.IntegerField() 13 pub_date=serializers.DateField() 14 publish=serializers.CharField(source="publish.name") 15 #authors=serializers.CharField(source="authors.all") 16 authors=serializers.SerializerMethodField() 17 def get_authors(self,obj): 18 temp=[] 19 for author in obj.authors.all(): 20 temp.append(author.name) 21 return temp 22 #此處能夠繼續用author的Serializers, 23 # def get_authors(self,obj): 24 # ret=obj.authors.all() 25 # ss=AuthorSerializer(ret,many=True) 26 # return ss.data 27 28 class BookViewSet(APIView): 29 30 def get(self,request,*args,**kwargs): 31 book_list=Book.objects.all() 32 # 序列化方式1: 33 # from django.forms.models import model_to_dict 34 # import json 35 # data=[] 36 # for obj in book_list: 37 # data.append(model_to_dict(obj)) 38 # print(data) 39 # return HttpResponse("ok") 40 41 # 序列化方式2: 42 # data=serializers.serialize("json",book_list) 43 # return HttpResponse(data) 44 45 # 序列化方式3: 46 bs=BookSerializers(book_list,many=True) #many=True表明有多條數據,若是隻有一條數據,many=False 47 return Response(bs.data) 48 # 序列化方式4: 49 # ret=models.Book.objects.all().values('nid','title') 50 # dd=list(ret) 51 # return HttpResponse(json.dumps(dd))
注意:html
source 若是是字段,會顯示字段,若是是方法,會執行方法,不用加括號(authors=serializers.CharField(source='authors.all'))如在模型中定義一個方法,直接能夠在在source指定執行python
class UserInfo(models.Model): user_type_choices = ( (1,'普通用戶'), (2,'VIP'), (3,'SVIP'), ) user_type = models.IntegerField(choices=user_type_choices) username = models.CharField(max_length=32,unique=True) password = models.CharField(max_length=64) #視圖 ret=models.UserInfo.objects.filter(pk=1).first() aa=ret.get_user_type_display() #serializer xx=serializers.CharField(source='get_user_type_display')
1 class BookSerializers(serializers.ModelSerializer): 2 class Meta: 3 model = models.Book 4 # fields = "__all__" 5 fields=['nid','title','authors','publish'] 6 # exclude=('nid',) #不能跟fields同時用 7 # depth = 1 #深度控制,寫 幾 往裏拿幾層,層數越多,響應越慢,官方建議0--10之間,我的建議最多3層 8 publish=serializers.SerializerMethodField() 9 def get_publish(self,obj): 10 return obj.publish.name 11 authors=serializers.SerializerMethodField() 12 def get_authors(self,obj): 13 ret=obj.authors.all() 14 ss=AuthorSerializer(ret,many=True) 15 return ss.data
1 class BookSerializers(serializers.ModelSerializer): 2 class Meta: 3 model = models.Book 4 fields = "__all__" 5 # 生成鏈接,直接查看出版社詳情 6 publish = serializers.HyperlinkedIdentityField(view_name='ttt', lookup_field='publish_id', lookup_url_kwarg='pkk') 7 authors=serializers.SerializerMethodField() 8 def get_authors(self,obj): 9 ret=obj.authors.all() 10 ss=AuthorSerializer(ret,many=True) 11 return ss.data 12 #-------------- 13 14 res=BookSerializers(ret,many=True,context={'request': request}) 15 16 #-------------- 17 18 class Publish(APIView): 19 def get(self,request,pkk): 20 print(pkk) 21 return HttpResponse('ok') 22 #----路由--- 23 url(r'^publish/(?P<pkk>\d+)$', views.Publish.as_view(),name='ttt'),
class BookSerializers(serializers.ModelSerializer): class Meta: model=Book fields="__all__" #———————— class BookView(APIView): def post(self, request): # 添加一條數據 print(request.data) bs=BookSerializers(data=request.data) if bs.is_valid(): bs.save() # 生成記錄 return Response(bs.data) else: return Response(bs.errors)
class BookSerializer1(serializers.Serializer): title=serializers.CharField(error_messages={'required': '標題不能爲空'}) #這種方式要保存,必須重寫create方法
經過源碼查看留的校驗字段的鉤子函數:sql
1 #is_valid---->self.run_validation-(執行Serializer的run_validation)-->self.to_internal_value(data)---(執行Serializer的run_validation:485行) 2 def validate_title(self, value): 3 from rest_framework import exceptions 4 raise exceptions.ValidationError('看你不順眼') 5 return value 6 7 #全局 8 def validate(self, attrs): 9 from rest_framework import exceptions 10 if attrs.get('title')== attrs.get('title2'): 11 return attrs 12 else: 13 raise exceptions.ValidationError('不想等啊')
1 ''' 2 序列化組件,先調用__new__方法,若是many=True,生成ListSerializer對象,若是爲False,生成Serializer對象 3 序列化對象.data方法--調用父類data方法---調用對象本身的to_representation(自定義的序列化類無此方法,去父類找) 4 Aerializer類裏有to_representation方法,for循環執行attribute = field.get_attribute(instance) 5 再去Field類裏去找get_attribute方法,self.source_attrs就是被切分的source,而後執行get_attribute方法,source_attrs 6 當參數傳過去,判斷是方法就加括號執行,是屬性就把值取出來 7 '''
圖書的增刪查改resful接口:數據庫
1 class BookSerializers(serializers.ModelSerializer): 2 class Meta: 3 model=models.Book 4 fields='__all__' 5 6 7 class BookView(APIView): 8 9 def get(self, request): 10 book_list = models.Book.objects.all() 11 bs = BookSerializers(book_list, many=True) 12 # 序列化數據 13 14 return Response(bs.data) 15 16 def post(self, request): 17 # 添加一條數據 18 print(request.data) 19 20 bs=BookSerializers(data=request.data) 21 if bs.is_valid(): 22 bs.save() # 生成記錄 23 return Response(bs.data) 24 else: 25 26 return Response(bs.errors) 27 28 class BookDetailView(APIView): 29 def get(self,request,pk): 30 book_obj=models.Book.objects.filter(pk=pk).first() 31 bs=BookSerializers(book_obj,many=False) 32 return Response(bs.data) 33 def put(self,request,pk): 34 book_obj = models.Book.objects.filter(pk=pk).first() 35 36 bs=BookSerializers(data=request.data,instance=book_obj) 37 if bs.is_valid(): 38 bs.save() # update 39 return Response(bs.data) 40 else: 41 return Response(bs.errors) 42 def delete(self,request,pk): 43 models.Book.objects.filter(pk=pk).delete() 44 45 return Response("")
1 url(r'^books/$', views.BookView.as_view()), 2 url(r'^books/(?P<pk>\d+)$', views.BookDetailView.as_view()),
只有認證經過的用戶才能訪問指定的url地址,好比:查詢課程信息,須要登陸以後才能查看,沒有登陸,就不能查看,這時候須要用到認證組件django
1 class User(models.Model): 2 username=models.CharField(max_length=32) 3 password=models.CharField(max_length=32) 4 user_type=models.IntegerField(choices=((1,'超級用戶'),(2,'普通用戶'),(3,'二筆用戶'))) 5 6 class UserToken(models.Model): 7 user=models.OneToOneField(to='User') 8 token=models.CharField(max_length=64)
1 from rest_framework.authentication import BaseAuthentication 2 class TokenAuth(): 3 def authenticate(self, request): 4 token = request.GET.get('token') 5 token_obj = models.UserToken.objects.filter(token=token).first() 6 if token_obj: 7 return 8 else: 9 raise AuthenticationFailed('認證失敗') 10 def authenticate_header(self,request): 11 pass
1 def get_random(name): 2 import hashlib 3 import time 4 md=hashlib.md5() 5 md.update(bytes(str(time.time()),encoding='utf-8')) 6 md.update(bytes(name,encoding='utf-8')) 7 return md.hexdigest() 8 class Login(APIView): 9 def post(self,reuquest): 10 back_msg={'status':1001,'msg':None} 11 try: 12 name=reuquest.data.get('name') 13 pwd=reuquest.data.get('pwd') 14 user=models.User.objects.filter(username=name,password=pwd).first() 15 if user: 16 token=get_random(name) 17 models.UserToken.objects.update_or_create(user=user,defaults={'token':token}) 18 back_msg['status']='1000' 19 back_msg['msg']='登陸成功' 20 back_msg['token']=token 21 else: 22 back_msg['msg'] = '用戶名或密碼錯誤' 23 except Exception as e: 24 back_msg['msg']=str(e) 25 return Response(back_msg) 26 27 28 29 class Course(APIView): 30 authentication_classes = [TokenAuth, ] 31 32 def get(self, request): 33 return HttpResponse('get') 34 35 def post(self, request): 36 return HttpResponse('post')
1 def get_token(id,salt='123'): 2 import hashlib 3 md=hashlib.md5() 4 md.update(bytes(str(id),encoding='utf-8')) 5 md.update(bytes(salt,encoding='utf-8')) 6 7 return md.hexdigest()+'|'+str(id) 8 9 def check_token(token,salt='123'): 10 ll=token.split('|') 11 import hashlib 12 md=hashlib.md5() 13 md.update(bytes(ll[-1],encoding='utf-8')) 14 md.update(bytes(salt,encoding='utf-8')) 15 if ll[0]==md.hexdigest(): 16 return True 17 else: 18 return False 19 20 class TokenAuth(): 21 def authenticate(self, request): 22 token = request.GET.get('token') 23 success=check_token(token) 24 if success: 25 return 26 else: 27 raise AuthenticationFailed('認證失敗') 28 def authenticate_header(self,request): 29 pass 30 class Login(APIView): 31 def post(self,reuquest): 32 back_msg={'status':1001,'msg':None} 33 try: 34 name=reuquest.data.get('name') 35 pwd=reuquest.data.get('pwd') 36 user=models.User.objects.filter(username=name,password=pwd).first() 37 if user: 38 token=get_token(user.pk) 39 # models.UserToken.objects.update_or_create(user=user,defaults={'token':token}) 40 back_msg['status']='1000' 41 back_msg['msg']='登陸成功' 42 back_msg['token']=token 43 else: 44 back_msg['msg'] = '用戶名或密碼錯誤' 45 except Exception as e: 46 back_msg['msg']=str(e) 47 return Response(back_msg) 48 from rest_framework.authentication import BaseAuthentication 49 class TokenAuth(): 50 def authenticate(self, request): 51 token = request.GET.get('token') 52 token_obj = models.UserToken.objects.filter(token=token).first() 53 if token_obj: 54 return 55 else: 56 raise AuthenticationFailed('認證失敗') 57 def authenticate_header(self,request): 58 pass 59 60 class Course(APIView): 61 authentication_classes = [TokenAuth, ] 62 63 def get(self, request): 64 return HttpResponse('get') 65 66 def post(self, request): 67 return HttpResponse('post')
總結:局部使用,只須要在視圖類里加入:json
authentication_classes = [TokenAuth, ] api
REST_FRAMEWORK={ "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",] }
1 #Request對象的user方法 2 @property 3 def user(self): 4 the authentication classes provided to the request. 5 if not hasattr(self, '_user'): 6 with wrap_attributeerrors(): 7 self._authenticate() 8 return self._user 9 10 def _authenticate(self): 11 for authenticator in self.authenticators: 12 try: 13 user_auth_tuple = authenticator.authenticate(self) 14 except exceptions.APIException: 15 self._not_authenticated() 16 raise 17 #認證成功,能夠返回一個元組,但必須是最後一個驗證類才能返回 18 if user_auth_tuple is not None: 19 self._authenticator = authenticator 20 self.user, self.auth = user_auth_tuple 21 return 22 23 self._not_authenticated()
self.authenticators跨域
def get_authenticators(self): return [auth() for auth in self.authentication_classes]
認證類使用順序:先用視圖類中的驗證類,再用settings裏配置的驗證類,最後用默認的驗證類數組
只用超級用戶才能訪問指定的數據,普通用戶不能訪問,因此就要有權限組件對其限制服務器
1 from rest_framework.permissions import BasePermission 2 class UserPermission(BasePermission): 3 message = '不是超級用戶,查看不了' 4 def has_permission(self, request, view): 5 # user_type = request.user.get_user_type_display() 6 # if user_type == '超級用戶': 7 user_type = request.user.user_type 8 print(user_type) 9 if user_type == 1: 10 return True 11 else: 12 return False 13 class Course(APIView): 14 authentication_classes = [TokenAuth, ] 15 permission_classes = [UserPermission,] 16 17 def get(self, request): 18 return HttpResponse('get') 19 20 def post(self, request): 21 return HttpResponse('post')
局部使用只須要在視圖類里加入:
permission_classes = [UserPermission,]
REST_FRAMEWORK={ "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",], "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",] }
1 def check_permissions(self, request): 2 for permission in self.get_permissions(): 3 if not permission.has_permission(request, self): 4 self.permission_denied( 5 request, message=getattr(permission, 'message', None) 6 )
self.get_permissions()
def get_permissions(self): return [permission() for permission in self.permission_classes]
權限類使用順序:先用視圖類中的權限類,再用settings裏配置的權限類,最後用默認的權限類
爲了控制用戶對某個url請求的頻率,好比,一分鐘之內,只能訪問三次
自定義的邏輯:
#(1)取出訪問者ip # (2)判斷當前ip不在訪問字典裏,添加進去,而且直接返回True,表示第一次訪問,在字典裏,繼續往下走 # (3)循環判斷當前ip的列表,有值,而且當前時間減去列表的最後一個時間大於60s,把這種數據pop掉,這樣列表中只有60s之內的訪問時間, # (4)判斷,當列表小於3,說明一分鐘之內訪問不足三次,把當前時間插入到列表第一個位置,返回True,順利經過 # (5)當大於等於3,說明一分鐘內訪問超過三次,返回False驗證失敗
代碼實現:
1 class MyThrottles(): 2 VISIT_RECORD = {} 3 def __init__(self): 4 self.history=None 5 def allow_request(self,request, view): 6 #(1)取出訪問者ip 7 # print(request.META) 8 ip=request.META.get('REMOTE_ADDR') 9 import time 10 ctime=time.time() 11 # (2)判斷當前ip不在訪問字典裏,添加進去,而且直接返回True,表示第一次訪問 12 if ip not in self.VISIT_RECORD: 13 self.VISIT_RECORD[ip]=[ctime,] 14 return True 15 self.history=self.VISIT_RECORD.get(ip) 16 # (3)循環判斷當前ip的列表,有值,而且當前時間減去列表的最後一個時間大於60s,把這種數據pop掉,這樣列表中只有60s之內的訪問時間, 17 while self.history and ctime-self.history[-1]>60: 18 self.history.pop() 19 # (4)判斷,當列表小於3,說明一分鐘之內訪問不足三次,把當前時間插入到列表第一個位置,返回True,順利經過 20 # (5)當大於等於3,說明一分鐘內訪問超過三次,返回False驗證失敗 21 if len(self.history)<3: 22 self.history.insert(0,ctime) 23 return True 24 else: 25 return False 26 def wait(self): 27 import time 28 ctime=time.time() 29 return 60-(ctime-self.history[-1])
寫一個類,繼承自SimpleRateThrottle,(根據ip限制)問:要根據用戶如今怎麼寫
1 from rest_framework.throttling import SimpleRateThrottle 2 class VisitThrottle(SimpleRateThrottle): 3 scope = 'luffy' 4 def get_cache_key(self, request, view): 5 return self.get_ident(request)
在setting裏配置:(一分鐘訪問三次)
1 REST_FRAMEWORK = { 2 'DEFAULT_THROTTLE_RATES':{ 3 'luffy':'3/m' 4 } 5 }
在視圖類裏使用
throttle_classes = [MyThrottles,]
錯誤信息的中文提示:
1 class Course(APIView): 2 authentication_classes = [TokenAuth, ] 3 permission_classes = [UserPermission, ] 4 throttle_classes = [MyThrottles,] 5 6 def get(self, request): 7 return HttpResponse('get') 8 9 def post(self, request): 10 return HttpResponse('post') 11 def throttled(self, request, wait): 12 from rest_framework.exceptions import Throttled 13 class MyThrottled(Throttled): 14 default_detail = '傻逼啊' 15 extra_detail_singular = '還有 {wait} second.' 16 extra_detail_plural = '出了 {wait} seconds.' 17 raise MyThrottled(wait)
內置頻率限制類:
BaseThrottle是全部類的基類:方法:def get_ident(self, request)獲取標識,其實就是獲取ip,自定義的須要繼承它
AnonRateThrottle:未登陸用戶ip限制,須要配合auth模塊用
SimpleRateThrottle:重寫此方法,能夠實現頻率如今,不須要我們手寫上面自定義的邏輯
UserRateThrottle:登陸用戶頻率限制,這個得配合auth模塊來用
ScopedRateThrottle:應用在局部視圖上的(忽略)
REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES':['app01.utils.VisitThrottle',], 'DEFAULT_THROTTLE_RATES':{ 'luffy':'3/m' } }
省略。。。。。。
1 from rest_framework.pagination import PageNumberPagination 2 # 一 基本使用:url=url=http://127.0.0.1:8000/pager/?page=2&size=3,size無效 3 class Pager(APIView): 4 def get(self,request,*args,**kwargs): 5 # 獲取全部數據 6 ret=models.Book.objects.all() 7 # 建立分頁對象 8 page=PageNumberPagination() 9 # 在數據庫中獲取分頁的數據 10 page_list=page.paginate_queryset(ret,request,view=self) 11 # 對分頁進行序列化 12 ser=BookSerializer1(instance=page_list,many=True) 13 return Response(ser.data) 14 # 二 自定製 url=http://127.0.0.1:8000/pager/?page=2&size=3 15 # size=30,無效,最多5條 16 class Mypage(PageNumberPagination): 17 page_size = 2 18 page_query_param = 'page' 19 # 定製傳參 20 page_size_query_param = 'size' 21 # 最大一頁的數據 22 max_page_size = 5 23 class Pager(APIView): 24 def get(self,request,*args,**kwargs): 25 # 獲取全部數據 26 ret=models.Book.objects.all() 27 # 建立分頁對象 28 page=Mypage() 29 # 在數據庫中獲取分頁的數據 30 page_list=page.paginate_queryset(ret,request,view=self) 31 # 對分頁進行序列化 32 ser=BookSerializer1(instance=page_list,many=True) 33 # return Response(ser.data) 34 # 這個也是返回Response對象,可是比基本的多了上一頁,下一頁,和總數據條數(瞭解便可) 35 return page.get_paginated_response(ser.data)
setting中配置:
REST_FRAMEWORK = { # 每頁顯示兩條 'PAGE_SIZE':2 }
路由: url(r'^pager/$', views.Pager.as_view()),
新建類: Serializers
1 class BookSerializer1(serializers.ModelSerializer): 2 class Meta: 3 model=models.Book 4 # fields="__all__" 5 exclude=('authors',)
1 # http://127.0.0.1:8000/pager/?offset=4&limit=3 2 from rest_framework.pagination import LimitOffsetPagination 3 # 也能夠自定製,同簡單分頁 4 class Pager(APIView): 5 def get(self,request,*args,**kwargs): 6 # 獲取全部數據 7 ret=models.Book.objects.all() 8 # 建立分頁對象 9 page=LimitOffsetPagination() 10 # 在數據庫中獲取分頁的數據 11 page_list=page.paginate_queryset(ret,request,view=self) 12 # 對分頁進行序列化 13 ser=BookSerializer1(instance=page_list,many=True) 14 # return page.get_paginated_response(ser.data) 15 return Response(ser.data)
1 from rest_framework.pagination import CursorPagination 2 # 看源碼,是經過sql查詢,大於id和小於id 3 class Pager(APIView): 4 def get(self,request,*args,**kwargs): 5 # 獲取全部數據 6 ret=models.Book.objects.all() 7 # 建立分頁對象 8 page=CursorPagination() 9 page.ordering='nid' 10 # 在數據庫中獲取分頁的數據 11 page_list=page.paginate_queryset(ret,request,view=self) 12 # 對分頁進行序列化 13 ser=BookSerializer1(instance=page_list,many=True) 14 # 能夠避免頁碼被猜到 15 return page.get_paginated_response(ser.data)