8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)

在前面的DRF系列教程中,以博客为例介绍了序列化器, 使用基于类的视图APIView和ModelViewSet开发了针对文章资源进行增删查改的完整API接口,并详细对权限和认证(含jwt认证)进行了总结与演示。在本篇文章中将向演示如何在Django REST Framework中使用分页。

参考文章:

3、DRF实战总结:基于类的视图APIView, GenericAPIView和GenericViewSet视图集(附源码)_SteveRocket的博客-CSDN博客

4、DRF实战总结:序列化器(Serializer)、数据验证、重写序列化器方法详解(附源码)_SteveRocket的博客-CSDN博客

https://blog.csdn.net/zhouruifu2015/article/details/129965342

https://blog.csdn.net/zhouruifu2015/article/details/129965353

分页

DRF中的分页是指将数据按照一定数量分割成多页的显示方法。每页显示一定的数据量,可以通过用户点击或者其他手段进行翻页操作。DRF分页的作用是在返回数据时,将数据分页显示,避免一次性返回大量数据导致网络传输不稳定、用户体验不佳等问题。

当的数据库数据量非常大时,如果一次将这些数据查询出来, 必然加大了服务器内存的负载,降低了系统的运行速度。一种更好的方式是将数据分段展示给用户。如果用户在展示的分段数据中没有找到自己的内容,可以通过指定页码或翻页的方式查看更多数据,直到找到自己想要的内容为止。

Django REST Framework提供3种分页类:

1. PageNumberPagination

简单分页器。非常常用的一种分页方式,其作用是将数据序列化后,返回符合要求的页码以及页码对应的数据列表。

支持用户按?page=3这种方式查询,可以通过page_size这个参数手动指定每页展示给用户数据的数量。它还支持用户按?page=3&size=10这种更灵活的方式进行查询,这样用户不仅可以选择页码,还可以选择每页展示数据的数量。对于第二种情况,通常还需要设置max_page_size这个参数限制每页展示数据的最大数量,以防止用户进行恶意查询(比如size=10000), 这样一页展示1万条数据将使分页变得没有意义。

2. LimitOffsetPagination

偏移分页器。作用是通过传入的"limit"和"offset"参数实现数据分页,其中"limit"为每页数据数,"offset"是从第几个数据开始返回。

支持用户按?limit=20&offset=100这种方式进行查询。offset是查询数据的起始点,limit是每页展示数据的最大条数,类似于page_size。当使用这个类时,通常还需要设置max_limit这个参数来限制展示给用户数据的最大数量。

3. CursorPagination

加密分页器。按照给定的排序方式将数据分页,每一页的分界点是另一页中最后一个数据的主键值。这种方式可以实现更为灵活的分页,因为它不受 limit 的限制,可以方便的实现“无限滚动式”或“加载更多”式的交互。

这是DRF提供的加密分页查询,仅支持用户按响应提供的上一页和下一页链接进行分页查询,每页的页码都是加密的。使用这种方式进行分页需要的模型有"created"这个字段,否则要手动指定ordering排序才能进行使用。

使用PageNumberPagination

DRF中使用默认分页类的最简单方式就是在settings.py中进行全局配置,如下所示:

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第1张图片

展示效果如下,每页展示两条记录, 不支持用户指定每页展示数据的数量。

如何查询一个超出内容数量的页数,则会提示Invalid page

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第2张图片

但是如果希望用户按?page=3&size=10这种更灵活的方式进行查询,就要进行个性化定制。在实际开发过程中,定制比使用默认的分页类更常见,具体做法如下。

在app目录下新建pagination.py, 添加如下代码:

#drf_pro/pagination.py

 
  

 

自定义了一个MyPageNumberPagination类,该类继承了PageNumberPagination类。通过page_size设置了每页默认展示数据的条数,通过page_size_query_param设置了每页size的参数名以及通过max_page_size设置了每页可以展示的最大数据条数。

使用自定义的分页类

在基于类的视图中,可以使用pagination_class这个属性使用自定义的分页类,如下所示:

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第3张图片

添加urls

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第4张图片

展示效果如下所示:

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第5张图片

当然定制分页类不限于指定page_size和max_page_size这些属性,还可以改变响应数据的输出格式。比如这里希望把next和previous放在一个名为links的key里,可以修改MyPageNumberPagination类,重写get_paginated_response方法:

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第6张图片

新的展示效果如下所示:

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第7张图片

注意:重写get_paginated_response方法非常有用,还可以给分页响应数据传递额外的内容,比如code状态码等等。

前面的例子中只在单个基于类的视图或视图集中使用到了分页类,还可以修改settings.py全局使用自定义的分页类,展示效果是一样的。

REST_FRAMEWORK = {

    'DEFAULT_PAGINATION_CLASS': 'blog.pagination.MyPageNumberPagination',

}

使用LimitOffsetPagination

使用这个分页类最简单的方式就是在settings.py中进行全局配置,如下所示:

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第8张图片

 

展示效果如下所示,从2页起,每页2条

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第9张图片

也可以自定义MyLimitOffsetPagination类,在单个视图或视图集中使用,或者全局使用。

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第10张图片

 

展示效果如下,从第2条数据查起,每页展示2条。

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第11张图片

使用CursorPagination

全局使用

REST_FRAMEWORK = {

    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',

    'PAGE_SIZE': 2

}

展示效果如下所示:

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第12张图片

使用CursorPagination类需要的模型里有created这个字段,否则需要手动指定ordering字段。这是因为CursorPagination类只能对排过序的查询集进行分页展示。Article模型只有create_date字段,没有created这个字段,所以会报错。

为了解决这个问题,需要自定义一个MyCursorPagination类,手动指定按create_date排序, 如下所示:

#drf_pro/pagination.py

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第13张图片

修改settings.py, 使用自己定义的分页类。

REST_FRAMEWORK = {

    'DEFAULT_PAGINATION_CLASS': 'blog.pagination.MyArticleCursorPagination',

}

响应效果如下所示,将得到previous和next分页链接。页码都加密了, 链接里不再显示页码号码。默认每页展示3条记录

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第14张图片

如果使用?page_size=2进行查询,每页将得到两条记录。

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第15张图片

当然由于这个ordering字段与模型相关,并不推荐全局使用自定义的CursorPagination类,更好的方式是在GenericsAPIView或视图集viewsets中通过pagination_class属性指定,如下所示:

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第16张图片

函数类视图中使用分页类

注意pagination_class属性仅支持在genericsAPIView和视图集viewset中配置使用。如果使用函数或简单的APIView开发API视图,那么需要对数据进行手动分页,如下示例所示:

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第17张图片

代码示例:https://download.csdn.net/download/zhouruifu2015/87657280

8、DRF实战总结:分页(Pagination)及DRF提供的分页类详解(附源码)_第18张图片

输入才有输出,吸收才能吐纳。——码字不易

你可能感兴趣的:(#,Django进阶,django,python,后端,分页)