Django Rest Framework(八)之分页
urls.py
from django.conf.urls import url,include from django.contrib import admin from api import views urlpatterns = [ url(r'^(?P<version>[v1|v2]+)/page/$',views.PagerViews.as_view()), ]
models.py
from django.db import models # Create your models here. class UserGroup(models.Model): title = models.CharField(max_length=32) 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) group = models.ForeignKey("UserGroup") roles = models.ManyToManyField("Role") class UserToken(models.Model): user = models.OneToOneField(to='UserInfo') token = models.CharField(max_length=64) class Role(models.Model): title = models.CharField(max_length=32)
使用django自带的分页类
views.py
from django.shortcuts import render,HttpResponse from rest_framework.views import APIViewfrom api import models from rest_framework.response import Response #渲染 from rest_framework.pagination import PageNumberPagination #系统自带的默认的分页方法
#序列化分页类
class PageSerializer(serializers.ModelSerializer): class Meta: model = models.Role fields = "__all__" class PagerViews(APIView): def get(self,request,*args,**kwargs): #①默认获取所有数据,不分页 # obj= models.Role.objects.all() # ser = PageSerializer(instance=obj,many=True) # return Response(ser.data) #②分页,获取所有数据 obj= models.Role.objects.all() #创建分页对象 pg = PageNumberPagination() pager_roles = pg.paginate_queryset(queryset=obj,request=request,view=self) #queryset表示从数据库拿数据,view为当前视图,为self ser = PageSerializer(instance=pager_roles, many=True) #print (pager_roles) #打印分页的结果对像 return Response(ser.data) #返回渲染的数据 #return pg.get_paginated_response(ser.data) #这里返回的数据中包含前一页和后一页的链接地址,
根据PageNumberPagination源码得知,设置分页的时候还需要定义page_size(即一页显示多少条数据),源码如下
class PageNumberPagination(BasePagination): page_size = api_settings.PAGE_SIZE #这里设置page_size django_paginator_class = DjangoPaginator # Client can control the page using this query parameter. page_query_param = 'page' page_query_description = _('A page number within the paginated result set.') page_size_query_param = None page_size_query_description = _('Number of results to return per page.') max_page_size = None last_page_strings = ('last',) template = 'rest_framework/pagination/numbers.html' invalid_page_message = _('Invalid page.')
所以设置settings.py
REST_FRAMEWORK = { "DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning", "DEFAULT_VERSION":"v1", "ALLOWED_VERSIONS":['v1','v2'], "VERSION_PARAM":'version', "DEFAULT_PARSER_CLASSES":['rest_framework.parsers.JSONParser','rest_framework.parsers.FormParser'], "PAGE_SIZE": 3 }
访问测试:http://127.0.0.1:8000/api/v1/page/?page=2

自定义分页类
from rest_framework.response import Response #渲染 from rest_framework.pagination import PageNumberPagination #f分页 #自定义分页类(字段均取自源码) class MyPageNumberPagination(PageNumberPagination): page_size = 4 #一页显示几条数据(源码里用的这个字段,不能变) page_size_query_param = 'size' max_page_size = 8 #一页最大显示多少条数据 page_query_param = 'page' #源码默认为page,可自定义。但是访问的时候参数要写对
class PageSerializer(serializers.ModelSerializer): class Meta: model = models.Role fields = "__all__" class PagerViews(APIView): def get(self,request,*args,**kwargs): #获取所有数据 obj= models.Role.objects.all() #创建分页对象pg = MyPageNumberPagination() pager_roles = pg.paginate_queryset(queryset=obj,request=request,view=self) #queryset表示从数据库拿数据,view为当前视图,为self ser = PageSerializer(instance=pager_roles, many=True) #print (pager_roles) return Response(ser.data) #这里同上 #return pg.get_paginated_response(ser.data) #这里同上
访问测试http://127.0.0.1:8000/api/v1/page/?page=1&size=5 表示一页显示5条数据

LimitOffsetPagination
urls.py 不变
views.py
from rest_framework.response import Response #渲染 from rest_framework.pagination import LimitOffsetPagination #导入Limit类 class PageSerializer(serializers.ModelSerializer): class Meta: model = models.Role fields = "__all__" class PagerViews(APIView): def get(self,request,*args,**kwargs): #获取所有数据 obj= models.Role.objects.all() #创建分页对象 pg = LimitOffsetPagination() #实例化Limit pager_roles = pg.paginate_queryset(queryset=obj,request=request,view=self) #queryset表示从数据库拿数据,view为当前视图,为self ser = PageSerializer(instance=pager_roles, many=True) #print (pager_roles) #return Response(ser.data) return pg.get_paginated_response(ser.data)
访问地址:http://127.0.0.1:8000/api/v1/page/?offset=1&limit=5 其中,offset索引从0开始,limit表示每页显示多少条数据

同样,根据limitoffsetPagenation源码也可以自定义分页类
LimitOffsetPagination一部分源码
class LimitOffsetPagination(BasePagination): default_limit = api_settings.PAGE_SIZE limit_query_param = 'limit' limit_query_description = _('Number of results to return per page.') offset_query_param = 'offset' offset_query_description = _('The initial index from which to return the results.') max_limit = None template = 'rest_framework/pagination/numbers.html'
根据源码自定义limit分页类
from rest_framework.response import Response #渲染 from rest_framework.pagination import LimitOffsetPagination #导入Limit类
#自定义Limit分页类 class MyLimitOffsetPagination(LimitOffsetPagination): # default_limit = api_settings.PAGE_SIZE #源码里用default_limit类指定限制每页多少条数据 default_limit = 2 limit_query_param = 'limit' offset_query_param = 'offset' max_limit = 5 #最大显示几条数据 class PageSerializer(serializers.ModelSerializer): class Meta: model = models.Role fields = "__all__" class PagerViews(APIView): def get(self,request,*args,**kwargs): #获取所有数据 obj= models.Role.objects.all() #创建分页对象 pg = myLimitOffsetPagination() #实例化Limit类 pager_roles = pg.paginate_queryset(queryset=obj,request=request,view=self) #queryset表示从数据库拿数据,view为当前视图,为self ser = PageSerializer(instance=pager_roles, many=True) #print (pager_roles) #return Response(ser.data) return pg.get_paginated_response(ser.data)
访问地址不变
加密分页 CursorPagination
urls.py不变
查看CursorPagination源码
class CursorPagination(BasePagination): cursor_query_param = 'cursor' cursor_query_description = _('The pagination cursor value.') page_size = api_settings.PAGE_SIZE invalid_cursor_message = _('Invalid cursor') ordering = '-created' #根据那个字段排序,-表示倒序
template = 'rest_framework/pagination/previous_and_next.html' page_size_query_param = None page_size_query_description = _('Number of results to return per page.') max_page_size = None
views.py(自定义加密分页类)
from rest_framework.response import Response #渲染
from rest_framework.pagination import CursorPagination #引入加密分页类
#自定义加密分页类
class MyCursorPagination(CursorPagination): cursor_query_param = 'cursor' #url参数 #page_size = api_settings.PAGE_SIZE #默认情况下,加密分页类也是用的page_size字段来显示几条数据 page_size = 2 ordering = 'id' #根据什么字段进行排序 page_size_query_param = "lll" #每页显示多少条数据的url参数 max_page_size = 4 template = 'rest_framework/pagination/previous_and_next.html' #结果渲染到哪个页面,可以自定义 class PageSerializer(serializers.ModelSerializer): class Meta: model = models.Role fields = "__all__" class PagerViews(APIView): def get(self,request,*args,**kwargs):
#获取所有数据 obj= models.Role.objects.all() #创建分页对象 pg = MyCursorPagination() #实例化加密分页对象 pager_roles = pg.paginate_queryset(queryset=obj,request=request,view=self) #queryset表示从数据库拿数据,view为当前视图,为self ser = PageSerializer(instance=pager_roles, many=True) #print (pager_roles) #return Response(ser.data) return pg.get_paginated_response(ser.data)
初次访问时访问地址 http://127.0.0.1:8000/api/v1/page/?lll=4 #lll代表每页显示几条数据


浙公网安备 33010602011771号