分页Pagination
当我们在PC 或者 App 有大量数据需要展示时,可以对数据进行分页展示。这时就用到了分页功能,分页使得数据更好的展示给用户
比如我们有1W+数据要返回给前端,数据量大一次性返回可能会比较慢,前端一次性展示1W+数据也会比较慢,用分页返回数据效果较好
前端分页和后端分页的区别
前端分页
前端分页是一次性把数据全部拿出来进行分页,比如500条数据,一次展示50条,点击下一页再展示下50条,依次类推
优缺点:
前端分页一次性把数据加载出来,翻页过程中不会再对后端发起请求,对服务器压力较小
但是当数据量过大的时候,比较耗费性能,加载速度会比较慢
后端分页
后端分页是根据前端的需求返回对应的数据给客户端,例如一共有500条数据,一次展示50条,前端传参请求一次只返回50条数据
传下一页的page再请求下一页的数据再返回50条
优缺点:
后端分页比较灵活,每次都单独请求数据,对前端性能要求不高, 更易保证数据准确性
因为每次翻页都需要请求后端拿到对应的数据,多用户同时请求会增加后端压力
如何选择分页
数据量比较小的时候建议一次性返回数据在前端进行分页,数据量庞大的话建议服务器分页单次请求单次返回
DRF中的分页
DRF中的分页介绍
在drf框架中允许自定制分页样式,可以设置每页显示的数量,并且支持以下操作
- 将分页链接作为响应内容的一部分
- 响应头中包含分页链接,比如Content-Range或Link
drf中使用通用视图或者视图集的时候会自动执行分页,如果使用的常规的APIView等,需要自己调用分页API
- 可以通过将分页类设置None来选择是否关闭分页功能
自有分页VIew源码示例
我们拿ListAPIView举例,ListAPIView继承mixins.ListModelMixin和GenericAPIView,下述代码可以看出源码本身包含了分页功能,如果使用常规VIew则需要自己实现对应逻辑
# ListModelMixin源码 如果是常规view要实现分页,在视图中实现下述代码即可 class ListModelMixin: def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) # self.paginate_queryset对原有的queryset数据集进行分页 page = self.paginate_queryset(queryset) # 如果页号不为空 if page is not None: #返回对应页的数据 serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) # 如果页号为空则返回全部数据 serializer = self.get_serializer(queryset, many=True) return Response(serializer.data)
分页的settings设置
DEFAULT_PAGINATION_CLASS和PAGE_SIZE必须同时设置,如果不设置或者只设置一个,就相当于是None不分页
REST_FRAMEWORK = { # drf的分页类位于rest_framework.pagination中 "DEFAULT_PAGINATION_CLASS":"",# 全局默认的指定分页类,如果视图想单独指定,与权限一样在view中单独设置 "PAGE_SIZE": #每一页显示多少数据 }
DRF中的分页类使用详解
BasePagination:
分页的基类,与权限、限流等原理一样,写好模版待后续具体逻辑继承,略过