一、分页器总结
1 内置了三种分页器 -PageNumberPagination:普通分页 -LimitOffsetPagination:偏移分页 -CursorPagination:游标分页 2 APIView和GenericAPIView+ListModelMixin 3 GenericAPIView+ListModelMixin的分页模式 4 PageNumberPagination:普通分页(用的最多) -page_size = api_settings.PAGE_SIZE # 每页显示多少条 -page_query_param = 'page' # 查询参数 -page_size_query_param = size # 查询的时候指定每页显示多少条 -max_page_size = 10 # 每页最多显示多少条 -使用方式: -定义一个类,继承PageNumberPagination -重写四个属性 -在继承了GenericAPIView+ListModelMixin视图类中配置 pagination_class = MyPageNumberPagination -查询 http://127.0.0.1:8000/students/?page=1&size=5 5 LimitOffsetPagination:偏移分页 -default_limit = api_settings.PAGE_SIZE # 默认条数 -limit_query_param = 'limit' # 查询时,指定查询多少条 -offset_query_param = 'offset' # 查询时,指定的起始位置是哪 -max_limit = None # 查询时,最多返回多少条 -使用方式: -定义一个类,继承LimitOffsetPagination -重写四个属性 -在继承了GenericAPIView+ListModelMixin视图类中配置 pagination_class = MyPageNumberPagination -查询 http://127.0.0.1:8000/students/?limit=100&offset=1 6 CursorPagination:游标分页(速度块) -cursor_query_param = 'cursor' # 查询的时候,指定的查询方式 -page_size = api_settings.PAGE_SIZE # 每页显示多少条 -ordering = '-created' # 排序方式 -page_size_query_param = size # 查询的时候指定每页显示多少条 -max_page_size = None #每页最多显示多少条 -使用方式: -定义一个类,继承LimitOffsetPagination -重写四个属性 -在继承了GenericAPIView+ListModelMixin视图类中配置 pagination_class = MyPageNumberPagination -查询 http://127.0.0.1:8000/students/?limit=100&offset=1 7 APIView的分页模式 -新建一个类,继承普通分页,重写四个属性 -视图类写法如下 class StudentApiView(APIView): def get(self,request): student_list=Student.objects.all() page=MyPageNumberPagination()# 实例化得到对象 # 只需要换不同的分页类即可 res=page.paginate_queryset(student_list,request,self)# 开始分页 ser=StudentSerializer(res,many=True) return page.get_paginated_response(ser.data) # 返回数据
二、内置的三种分页代码
models.py
from django.db import models class Student(models.Model): name = models.CharField(max_length=32) sex = models.SmallIntegerField(choices=((1, '男'), (2, '女'), (3, '未知')), default=1) age = models.IntegerField()
serializer.py
from rest_framework import serializers from app01.models import Student class StudentSerializer(serializers.ModelSerializer): sex=serializers.CharField(source='get_sex_display') class Meta: model = Student fields='__all__'
views.py
from app01.serializer import StudentSerializer from app01.models import Student from rest_framework.viewsets import ViewSetMixin,GenericViewSet from rest_framework.mixins import ListModelMixin from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination class MyPageNumberPagination(PageNumberPagination): page_size = 3 page_query_param = 'page' page_size_query_param = 'size' max_page_size = 5 class MyLimitOffsetPagination(LimitOffsetPagination): default_limit = 2 # 默认条数 limit_query_param = 'limit' # 查询时,指定查询多少条 offset_query_param = 'offset' # 查询时,指定的起始位置是哪 max_limit = 5 # 查询时,最多返回多少条 class MyCursorPagination(CursorPagination): cursor_query_param = 'cursor' # 查询的时候,指定的查询方式 page_size = 2 # 每页显示多少条 ordering = 'id' # 排序方式,一定要指定排序方式,就是model中的可以排序的字段 # page_size_query_param = 'size' # 查询的时候指定每页显示多少条 # max_page_size = 5 # 每页最多显示多少条 # class StudentView(GenericViewSet,ListAPIView): class StudentView(GenericViewSet,ListModelMixin): queryset = Student.objects.all() serializer_class = StudentSerializer # 普通分页(用的多) # pagination_class = MyPageNumberPagination # pagination_class = PageNumberPagination # 偏移分页 # pagination_class = MyLimitOffsetPagination # 游标分页 pagination_class = MyCursorPagination
#如果想让每页显示条数自动化,需在settings.py中配置(可以不同它,直接在视图函数中写也行)
REST_FRAMEWORK = { 'PAGE_SIZE':3, #每页数目 }
urls.py 自动生成路由
from django.contrib import admin from django.urls import path from app01 import views from rest_framework.routers import SimpleRouter router = SimpleRouter() router.register('students', views.StudentView) from rest_framework.documentation import include_docs_urls urlpatterns = [ path('admin/', admin.site.urls), ] urlpatterns += router.urls #这句千万要记得!
三、继承APIView的分页模式 代码
models.py 和serializer.py同上
views.py
from app01.serializer import StudentSerializer from app01.models import Studentfrom rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination class MyPageNumberPagination(PageNumberPagination): page_size = 3 page_query_param = 'page' page_size_query_param = 'size' max_page_size = 5 class MyLimitOffsetPagination(LimitOffsetPagination): default_limit = 2 # 默认条数 limit_query_param = 'limit' # 查询时,指定查询多少条 offset_query_param = 'offset' # 查询时,指定的起始位置是哪 max_limit = 5 # 查询时,最多返回多少条 class MyCursorPagination(CursorPagination): cursor_query_param = 'cursor' # 查询的时候,指定的查询方式 page_size = 2 # 每页显示多少条 ordering = 'id' # 排序方式,一定要指定排序方式,就是model中的可以排序的字段 # page_size_query_param = 'size' # 查询的时候指定每页显示多少条 # max_page_size = 5 # 每页最多显示多少条 ## 如果继承Apiview,分页方式的使用 from rest_framework.views import APIView from rest_framework.response import Response class StudentApiView(APIView): def get(self,request): # 自己进行分页 student_list=Student.objects.all() # 进行分页 # 实例化得到分页对象,想用哪种方式分页就用哪种 # page=MyPageNumberPagination() # page=MyLimitOffsetPagination() page=MyCursorPagination() res=page.paginate_queryset(student_list,request,self) ser=StudentSerializer(res,many=True) # 把分页后的数据放到里面 # return Response(ser.data) #这个样式不好看,用下面的 return page.get_paginated_response(ser.data)
#或者用下面的,下面的是根据源码里的方法得知的
# return APIResponse(data=ser.data,count=student_list.count(),next=page.get_next_link())
urls.py
urlpatterns = [ path('student_apiview/', views.StudentApiView.as_view()), ]