Django rest_framework 中分页可分为三类:
- PageNumberPagination:看第 n 页,每页显示 n 条数据
- LimitOffsetPagination:在 n 个位置,向后查看 n 条数据
- CursorPagination:加密分页,只能看上一页和下一页
一、PageNumberPagination
在这里将采用 rest_framework
内置的页面渲染器 Response
。
1、api/serializers.py
class PagesSerializers(serializers.ModelSerializer): """分页""" class Meta: model = models.Role fields = '__all__'
2、api/views.py
from rest_framework.response import Response # 渲染器 from .serializers import PagesSerializers from app import models from rest_framework.pagination import PageNumberPagination class PageView(APIView): """分页""" def get(self, request, *args, **kwargs): """示例: http://api.example.org/accounts/?page=4 http://api.example.org/accounts/?page=4&page_size=100 """ roles = models.Role.objects.all() # 创建分页对象 pg = PageNumberPagination() # 获取分页数据 page_roles = pg.paginate_queryset(queryset=roles, request=request, view=self) # 将分页后的数据序列化 roles_ser = PagesSerializers(instance=page_roles, many=True) # 将序列化后的数据渲染到前端显示,这里采用的是 rest_framework 的渲染器 Response return Response(roles_ser.data)
3、api/urls.py
from django.urls import path, re_path from api.views import UserView, ParserView, RolesView, UserInfoView, GroupView, UserGroupView, PageView urlpatterns = [ re_path('(?P<version>[v1|v2]+)/pages/', PageView.as_view()), # 分页 ]
4、另外需要配置每页显示的条数 settings.py
REST_FRAMEWORK = { "DEFAULT_VERSION": 'v1', # 默认的版本 "ALLOWED_VERSIONS": ['v1', 'v2'], # 允许的版本 "VERSION_PARAM": 'version', # GET方式url中参数的名字 ?version=xxx "PAGE_SIZE": 2, # 每页最多显示两条数据 }
5、访问(第二页数据):http://127.0.0.1:8000/api/v2/pages/?page=2

自定义分页
定义一个类,让它继承 PageNumberPagination
1、api/views.py
class MyPageNumberPagination(PageNumberPagination): """自定义分页类""" page_size = 2 # 每页最多显示的条数 page_query_param = 'page' # 查询参数,URL 中的过滤参数 # 通过 page_size 每页只显示 2 条,使用下面这个参数可以改变默认显示条数 # 使用方法 http://127.0.0.1:8000/api/v2/pages/?page=2&size=3 page_size_query_param = 'size' max_page_size = 10 # 最大页数 class PageView(APIView): """分页""" def get(self, request, *args, **kwargs): """ http://api.example.org/accounts/?page=4 http://api.example.org/accounts/?page=4&page_size=100 """ roles = models.Role.objects.all() # 创建分页对象 # pg = PageNumberPagination() pg = MyPageNumberPagination() # 获取分页数据 page_roles = pg.paginate_queryset(queryset=roles, request=request, view=self) # 将分页后的数据序列化 roles_ser = PagesSerializers(instance=page_roles, many=True) # 将序列化后的数据渲染到前端显示,这里采用的是 rest_framework 的渲染器 Response return Response(roles_ser.data)
2、访问:http://127.0.0.1:8000/api/v2/pages/?page=2&size=1

二、LimitOffsetPagination
LimitOffsetPagination
可以控制只查看多少条,以及偏移量 offset
后多少条数据,格式为:
http://api.example.org/accounts/?limit=100 # 控制查看 100 条数据 http://api.example.org/accounts/?offset=400&limit=100 # 偏移量 400,查看条数 100,即查看 400 后的 100 条数据
使用方法与 PageNumberPagination
一致:
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination class PageView(APIView): """分页""" def get(self, request, *args, **kwargs): """ http://api.example.org/accounts/?page=4 http://api.example.org/accounts/?page=4&page_size=100 """ roles = models.Role.objects.all() # 创建分页对象 # pg = PageNumberPagination() # pg = MyPageNumberPagination() pg = LimitOffsetPagination() # 获取分页数据 page_roles = pg.paginate_queryset(queryset=roles, request=request, view=self) # 将分页后的数据序列化 roles_ser = PagesSerializers(instance=page_roles, many=True) # 将序列化后的数据渲染到前端显示,这里采用的是 rest_framework 的渲染器 Response return Response(roles_ser.data)
查看第 2 条数据后的 3 条数据:

自定义
同样地 LimitOffsetPagination
也支持自定义:
#自定义分页类2 class MyLimitOffsetPagination(LimitOffsetPagination): #默认显示的个数 default_limit = 2 #当前的位置 offset_query_param = "offset" #通过limit改变默认显示的个数 limit_query_param = "limit" #一页最多显示的个数 max_limit = 10
get_paginated_response() 方法控制前后页面
api/views.py
class PageView(APIView): """分页""" def get(self, request, *args, **kwargs): """ http://api.example.org/accounts/?page=4 http://api.example.org/accounts/?page=4&page_size=100 """ roles = models.Role.objects.all() # 创建分页对象 # pg = PageNumberPagination() # pg = MyPageNumberPagination() pg = LimitOffsetPagination() # 获取分页数据 page_roles = pg.paginate_queryset(queryset=roles, request=request, view=self) # 将分页后的数据序列化 roles_ser = PagesSerializers(instance=page_roles, many=True) # 将序列化后的数据渲染到前端显示,这里采用的是 rest_framework 的渲染器 Response # return Response(roles_ser.data) return pg.get_paginated_response(roles_ser.data) # 这一行
效果如下:

三、CursorPagination
CursorPagination
将页码进行加密,使得不能通过 URL 来控制显示的页面
1、这里使用自定义分页类 api/views.py
class MyCursorPagination(CursorPagination): """自定义分页类""" page_size = 2 # 每页最多显示的条数 cursor_query_param = 'cursor' # 查询参数,URL 中的过滤参数 ordering = 'id' # 通过什么排序(正序) page_size_query_param = None max_page_size = None # 最大页数 class PageView(APIView): """分页""" def get(self, request, *args, **kwargs): """ http://api.example.org/accounts/?page=4 http://api.example.org/accounts/?page=4&page_size=100 """ roles = models.Role.objects.all() # 创建分页对象 # pg = PageNumberPagination() # pg = MyPageNumberPagination() # pg = LimitOffsetPagination() pg = MyCursorPagination() # 获取分页数据 page_roles = pg.paginate_queryset(queryset=roles, request=request, view=self) # 将分页后的数据序列化 roles_ser = PagesSerializers(instance=page_roles, many=True) # 将序列化后的数据渲染到前端显示,这里采用的是 rest_framework 的渲染器 Response # return Response(roles_ser.data) return pg.get_paginated_response(roles_ser.data)
2、访问: http://127.0.0.1:8000/api/v2/pages/
