分页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则需要自己实现对应逻辑
  1. # ListModelMixin源码 如果是常规view要实现分页,在视图中实现下述代码即可
  2. class ListModelMixin:
  3. def list(self, request, *args, **kwargs):
  4. queryset = self.filter_queryset(self.get_queryset())
  5. # self.paginate_queryset对原有的queryset数据集进行分页
  6. page = self.paginate_queryset(queryset)
  7. # 如果页号不为空
  8. if page is not None:
  9. #返回对应页的数据
  10. serializer = self.get_serializer(page, many=True)
  11. return self.get_paginated_response(serializer.data)
  12. # 如果页号为空则返回全部数据
  13. serializer = self.get_serializer(queryset, many=True)
  14. return Response(serializer.data)
 
 
分页的settings设置
DEFAULT_PAGINATION_CLASS和PAGE_SIZE必须同时设置,如果不设置或者只设置一个,就相当于是None不分页
  1. REST_FRAMEWORK = {
  2. # drf的分页类位于rest_framework.pagination中
  3. "DEFAULT_PAGINATION_CLASS":"",# 全局默认的指定分页类,如果视图想单独指定,与权限一样在view中单独设置
  4. "PAGE_SIZE": #每一页显示多少数据
  5. }
 

DRF中的分页类使用详解

BasePagination:
分页的基类,与权限、限流等原理一样,写好模版待后续具体逻辑继承,略过
PageNumberPagination:
继承BasePagination,这种分页接收前端请求的页码参数,参数是第几页则请求第几页的数据,例如前端请求page=10,则返回第10页数据
  1. # settings.py
  2. REST_FRAMEWORK = {
  3. # 指定分页类为PageNumberPagination
  4. "DEFAULT_PAGINATION_CLASS":"rest_framework.pagination.PageNumberPagination",
  5. "PAGE_SIZE":3 #每一页显示3条数据
  6. }
如果是基于通用视图或者视图集,当前已经实现了分页功能
  • 图1是没有设置分页时候的请求,返回全部6条数据
  • 图2设置了分页后,默认不传page参数的请默认返回了第一页的数据
  • 图3请求地址后加了page参数,page=2,则返回的是第二页的数据
  • 也可以看出设置分页后response多了三个参数count是接口一共的数量,next是下一页的地址,previous是上一页地址
PageNumberPagination自定义分页类
上述方式每页请求的数据量是根据settings设置PAGE_SIZE写死的数量进行返回,如果我们想要根据传参定义第几页返回多少条数据,可以自定义分页类
  1. from rest_framework import pagination
  2. # 继承分页类
  3. class PublicPagination(pagination.PageNumberPagination):
  4. page_size = 2 # 每页显示的默认数据个数
  5. page_query_param = 'page' # 页号,第几页的参数 ,比如定义为pages,那么请求分页的参数就应该是pages
  6. page_size_query_param = 'page_size' # 自己指定每页显示多少个数
  7. max_page_size = 100 # 最大允许设置的每页显示的数量
  8. # last_page_strings用于指定表示请求最后一页的参数
  9. # page=last的时候会直接到最后一页
  10. # 如果不改参数的话,可以不用设置,不设置的话默认参数就是last
  11. last_page_strings = 'last'
  12. '''
  13. 自定义分页类
  14. 通过page_size指定默认的每页数据量,
  15. page_size_query_param指定每页自定义的数据量的参数,如果请求page_size=4,则每页显示4个,否则走默认的2
  16. max_page_size是允许设置的每页最大的数据量
  17. '''
  1. # 导入自定义的分页类
  2. from .pagination import PublicPagination
  3. class CategoryViewSet(ModelViewSet):
  4. queryset = Category.objects.all()
  5. serializer_class = CategorySerializer
  6. # 指定自定义的分页类,与权限、限量等不同,每个视图只允许指定一个分页类
  7. # 对指定视图设置分页类,会覆盖settings中默认的全局配置
  8. pagination_class = PublicPagination
上述代码实现对应功能后,继续请求接口
  • 图1page=2,请求第二页的数据,返回2条,因为自定义分页类中的page_size覆盖了全局的page_size=3
  • 图2没有指定page参数,默认返回第一页的两条数据
  • 图3指定page=2,page_size=1,返回第二页的数据,用page_size指定1覆盖代码中设置的2,所以只显示1条数据
 
LimitOwsetPagination:
这个分页类就类似于查找数据库中查找的语法
比如数据库中 Select * from table limit 100,300,从第101条开始,取300的数据
在分页中limit用于指定取多少条数据,offset用于指定从多少条开始,与sql一样,offse+1开始
  1. #view
  2. class CategoryViewSet(ModelViewSet):
  3. queryset = Category.objects.all()
  4. serializer_class = CategorySerializer
  5. # 给该指定LimitOffsetPagination分页类,也可以在settings指定全局
  6. pagination_class = LimitOffsetPagination
下面使用LimitOwsetPagination分页类请求接口
  • 图1,没有传参返回了3条数据是因为在settings中page_size是3,默认从第一条开始取3条数据,下一页依次向后取3条
  • 图2是将settings中的page_size删除掉,没有传递limit和offset参数就默认全部返回
  • 图3是传入limit=2,offset=2,从第三条开始取2条数据
LimitOwsetPagination自定义分页类
  1. # 继承LimitOffsetPagination分页类
  2. class PublicLimitOffsetPagination(pagination.LimitOffsetPagination):
  3. default_limit = 2 # 用于指定默认的limit数量
  4. limit_query_param = 'lm' # 指定请求时候对应的limit参数名,如果是lm那么传参就是lm=
  5. offset_query_param = 'of' ## 指定请求时候对应的offset参数名,如果是lm那么传参就是of=
  6. max_limit = 4 # 最大的limit可设置数量

CursorPagination:

基于光标的分页
CursorPagination分页类说明
  • 显示一个正向和反向的控件,不允许我们任意导航到任意位置
  • 要求结果集中有应该唯一的不变的排序方式
  • 可以确保客户端在翻页时不会看到同一对象两次,即使在分页的同时有数据插入
  • 对于超级大的数据量,使用前两个分页可能会效率低下,基于光标的分页具有固定的时间属性,不会因为数据变大而减慢
  • 基于光标的分页的排序方式默认是使用created排序,如果使用默认排序则模型必须有created时间戳字段,首先显示最近添加的数据
  • 可以覆盖pagination类的ordering属性,或者使用OrderingFilter过滤器类和CursorPagination来修改排序
  • 使用时要注意应该有一个唯一不变的值,例如默认的created
  1. #settings设置
  2. REST_FRAMEWORK = {
  3. # 指定CursorPagination分页类
  4. "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.CursorPagination",
  5. "PAGE_SIZE": 2 # 每一页显示3条数据
  6. }
 

通过光标进行的分页,可以看出next后面的参数进行了加密,无法直接通过传递参数进行跳转,只能一页一页点击
自定义CursorPagination
  1. #继承CursorPagination分页类
  2. class PublicCursorPagination(pagination.CursorPagination):
  3. ordering = '-created' #通过什么进行排序,默认created
  4. page_size = 3 # 每页数据量
  5. cursor_query_param = 'cs' #请求的参数字段,默认cursor

47.DRF实现分页的更多相关文章

  1. DRF的分页

    DRF的分页   DRF的分页 为什么要使用分页 其实这个不说大家都知道,大家写项目的时候也是一定会用的, 我们数据库有几千万条数据,这些数据需要展示,我们不可能直接从数据库把数据全部读取出来, 这样 ...

  2. DRF框架(九)——drf偏移分页组件、drf游标分页组件(了解)、自定义过滤器、过滤器插件django-filter

    drf偏移分页组件 paginations.py from rest_framework.pagination import LimitOffsetPagination class MyLimitOf ...

  3. drf偏移分页组件-游标分页-自定义过滤器-过滤器插件django-filter

    drf偏移分页组件 LimitOffsetPagination 源码分析:获取参数 pahenations.py from rest_framework.pagination import Limit ...

  4. drf 的分页功能

    1 settings中配置 page_size = 20 代表每页20条数据 REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': ( 'rest_framewor ...

  5. DRF之频率限制、分页、解析器和渲染器

    一.频率限制 1.频率限制是做什么的 开放平台的API接口调用需要限制其频率,以节约服务器资源和避免恶意的频繁调用. 2.频率组件原理 DRF中的频率控制基本原理是基于访问次数和时间的,当然我们可以通 ...

  6. DRF 分页组件

    Django Rest Framework 分页组件 DRF的分页 为什么要使用分页 其实这个不说大家都知道,大家写项目的时候也是一定会用的, 我们数据库有几千万条数据,这些数据需要展示,我们不可能直 ...

  7. DRF频率、分页、解析器、渲染器

    DRF的频率 频率限制是做什么的 开放平台的API接口调用需要限制其频率,以节约服务器资源和避免恶意的频繁调用. 频率组件原理 DRF中的频率控制基本原理是基于访问次数和时间的,当然我们可以通过自己定 ...

  8. DRF之注册响应分页组件

    注册器 注册器的作用就是以后我们不用自己手动的一条条的敲路径了,它可以帮助哦们直接去找对应的路由,不用传参了,知道这一点就可以了,不多说还是,上代码实例 第一步:导入模块from django.url ...

  9. DRF框架(八)——drf-jwt手动签发与校验、搜索过滤组件、排序过滤组件、基础分页组件

    自定义drf-jwt手动签发和校验 签发token源码入口 前提:给一个局部禁用了所有 认证与权限 的视图类发送用户信息得到token,其实就是登录接口,不然进不了登录页面 获取提交的username ...

  10. drf-jwt手动签发与校验,drf小组件:过滤、筛选、排序、分页

    复习 """ 频率组件:限制接口的访问频率 源码分析:初始化方法.判断是否有权限方法.计数等待时间方法 自定义频率组件: class MyThrottle(SimpleR ...

随机推荐

  1. aws-s3-国际global与国内CN的一些说明

    S3云存储国际版最近经常被墙,国内部分地区有时能正常上传下载,有时也会直接报错网络错误等信息, 所以建议S3使用国内AWS的.国内S3与国外S3在使用时需要注意以下几点: 1)URL不通用 国际版的S ...

  2. PHP全栈开发(八):CSS Ⅹ 导航栏制作

    学习了这么久的CSS,我们现在也可以小试牛刀一下了,我们使用我们学会的CSS知识来制作一个导航栏. 我们都知道,在现代的导航栏里面,最普遍的就是使用无序列表来制作导航栏. 我们可以使用如下代码来制作一 ...

  3. 文盘Rust -- struct 中的生命周期

    最近在用rust 写一个redis的数据校验工具.redis-rs中具备 redis::ConnectionLike trait,借助它可以较好的来抽象校验过程.在开发中,不免要定义struct 中的 ...

  4. python的基本运用

    python基础 Python语言是一种解释型.面向对象.动态数据类型的高级程序设计语言 开发者:Guido van Rossum(人称龟叔) 基本概念 1.变量 变量名必须是大小写英文字母.数字或下 ...

  5. GMOJ5673 爬山法 题解

    Solution 显然先想到处理出每个点能看到的最高的顶点. 然后考虑模拟题目的过程,一段一段走时间复杂度显然不够优秀. 考虑我们要求什么,我们需要求出\(u\)到\(v\)的最近的一个点,使得这个点 ...

  6. Oracle 同义词详解(synonym)

    Oracle 同义词详解(synonym) 一.Oracle同义词概念 Oracle 数据库中提供了同义词管理的功能.同义词是数据库方案对象的一个别名,经常用于简化对象访问和提高对象访问的安全性.在使 ...

  7. C语言编译环境中的 调试功能及常见错误提示

    文章目录 1 .调试功能 2 . 编译中的常见错误例析 3 .常见错误信息语句索引 1 .调试功能 1.常用健 <F10> : 激活系统菜单 <F6> : 将光标在编辑窗口和. ...

  8. Xmake v2.7.3 发布,包组件和 C++ 模块增量构建支持

    Xmake 是一个基于 Lua 的轻量级跨平台构建工具. 它非常的轻量,没有任何依赖,因为它内置了 Lua 运行时. 它使用 xmake.lua 维护项目构建,相比 makefile/CMakeLis ...

  9. Jmeter添加性能监控插件监控被测系统资源

    使用jmeter来监控服务器资源(CPU.I/O.内存.网络等),需要安装jmeter性能监控插件以及在被测服务器中启动监控服务. 一.下载并安装插件 下载 Plugins Manager插件管理器, ...

  10. jupyter notebook使用相对路径的方法

    在当前文件夹路径下开启jupyter notebook 这样就可以直接使用相对路径了,而不用管绝对路径这一令人心烦的问题 首先需要重新安装PowerShell 下载链接:https://cloud.1 ...