''' 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)