Django rest framework 之分页

大憨熊 提交于 2019-11-27 22:16:36

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/

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!