为什么要使用分页?
我们数据表中可能会有成千上万条数据, 当我们访问某张表的所有数据时, 我们不太可能需要一次把所有的数据都展示出来, 因为数据量很大, 对服务端的内存压力比较大还有就是网络传输过程中耗时也会比较大.
通常我们会希望一部分一部分去请求数据, 也就是我们常说的一页一页获取数据并展示出来.
REST framework 中提供了三种分页模式
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
全局配置
- REST_FRAMEWORK = {
- 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
- 'PAGE_SIZE': 100
- }
局部配置
- class PublisherViewSet(ModelViewSet):
- queryset = models.Publisher.objects.all()
- serializer_class = PublisherModelSerializer
- pagination_class = PageNumberPagination # 注意不是列表 (只能有一个分页模式)
第一种: PageNumberPagination
按页码数分页, 第 n 页, 每页显示 m 条数据
例如: http://127.0.0.1:8000/api/article/?page=2&size=1
分页器
- class MyPageNumber(PageNumberPagination):
- page_size = 2 # 每页显示多少条
- page_size_query_param = 'size' # URL 中每页显示条数的参数 KEY
- page_query_param = 'page' # URL 中页码的参数
- max_page_size = None # 最大页码数限制
视图
- class ArticleList(APIView):
- def get(self, request, *args, **kwargs):
- res = {"code": 0}
- article_list = models.Article.objects.all().order_by("id")
- # 分页
- page_obj = MyPageNumber()
- page_article = page_obj.paginate_queryset(queryset=article_list, request=request, view=self)
- ser_obj = ArticleSerializer(page_article, many=True)
- res["data"] = ser_obj.data
- return Response(res)
返回带页码连接的响应
- class ArticleList(APIView):
- def get(self, request, *args, **kwargs):
- res = {"code": 0}
- article_list = models.Article.objects.all().order_by("id")
- # 分页
- page_obj = MyPageNumber()
- page_article = page_obj.paginate_queryset(queryset=article_list, request=request, view=self)
- ser_obj = ArticleSerializer(page_article, many=True)
- res["data"] = ser_obj.data
- return page_obj.get_paginated_response(res)
第二种: LimitOffsetPagination
分页, 在 n 位置, 向后查看 m 条数据, 数据库查询时效率较高
例如: http://127.0.0.1:8000/api/article/?offset=2&limit=2
分页器
- # offset 分页
- class MyLimitOffset(LimitOffsetPagination):
- default_limit = 1
- limit_query_param = 'limit'
- offset_query_param = 'offset'
- max_limit = 999
视图
- class ArticleList(APIView):
- def get(self, request, *args, **kwargs):
- res = {"code": 0}
- article_list = models.Article.objects.all().order_by("id")
- # 分页
- page_obj = MyLimitOffset()
- page_article = page_obj.paginate_queryset(queryset=article_list, request=request, view=self)
- ser_obj = ArticleSerializer(page_article, many=True)
- res["data"] = ser_obj.data
- return page_obj.get_paginated_response(res)
自定义
- # 当有特殊的配置需要代替默认的配置时, 我们就自己写个类
- class MyLimitPager(LimitOffsetPagination):
- limit_query_param = 'page_size' # 自定义 limit 的参数 key
- pass
第三种: CursorPagination
加密分页, 把上一页和下一页的 id 值记住
分页器
- # 加密分页
- class MyCursorPagination(CursorPagination):
- cursor_query_param = 'cursor'
- page_size = 1
- ordering = '-id' # 重写要排序的字段
视图
- class ArticleList(APIView):
- def get(self, request, *args, **kwargs):
- res = {"code": 0}
- article_list = models.Article.objects.all().order_by("id")
- # 分页
- page_obj = MyCursorPagination()
- page_article = page_obj.paginate_queryset(queryset=article_list, request=request, view=self)
- ser_obj = ArticleSerializer(page_article, many=True)
- res["data"] = ser_obj.data
- # return Response(res)
- return page_obj.get_paginated_response(res)
解析器和渲染器
配置
- # 解析器
- 'DEFAULT_PARSER_CLASSES': (
- 'rest_framework.parsers.JSONParser',
- 'rest_framework.parsers.FormParser',
- 'rest_framework.parsers.MultiPartParser'
- ),
- # 渲染器
- # 你要页面 我就给你页面
- # 你要 JSON 格式的数据 我就给你 JSON 格式的数据
- 'DEFAULT_RENDERER_CLASSES': (
- 'rest_framework.renderers.JSONRenderer',
- # 'rest_framework.renderers.BrowsableAPIRenderer',
- ),
来源: https://www.cnblogs.com/konghui/p/10279611.html