Django REST Framework之分页器

Django REST Framework提供了三种分页器:

  1. PageNumberPagination。基于Django Paginator封装,使得操作更方便,只需要做一些配置即可。分页方式:根据页数和每页的大小进行分页。
  2. LimitOffsetPagination。分页方式:从第几条开始找,向后找多少条。
  3. CursorPagination。实现比较复杂,有自己的特点。

说明:一般在分页前,需要先将数据排序。如果不排序,会报警告

PageNumberPagination

utils/pagination.py

from rest_framework.pagination import PageNumberPagination

class MyPagination(PageNumberPagination):
    # 只需要做一些配置即可
    page_size = 1   # 每页的数据量(默认)
    page_query_param = "page" # 请求参数中的 page参数名
    page_size_query_param = "size" # 请求参数中的 page_size参数名
    max_page_size = 3 # 每页最大数量,请求参数中如果超过了这个配置,不会报错,会按照此配置工作

需要说明的是:我们配置的参数名,需要使用get请求。DRF在实现过程中只是针对get获取参数,如果需要其他方式传递参数(如post),需要自己修改源码。

views.py

from utils.pagination import MyPagination

class BookView(APIView):
    def get(self, request):
        book_list = Book.objects.all().order_by("id")

        # 实例化分页器对象
        pageObj = MyPagination()     #  PageNumberPagination
        # 调用分页方法
        page_query = pageObj.paginate_queryset(book_list, request, view=self)
        # 序列化器 many表示取出多条数据
        ret = BookSeriallzer(page_query, myFields="__all__", many=True) 
        print(ret)
    
        resIO = pageObj.get_paginated_response(ret.data) # 获取分页的结果,将分页后的结果数据与Response封装在一起
        # 将数据分为count,next,prev,result。分别是数据总量,上一页/下一页的请求地址,本页的数据

        return resIO

LimitOffsetPagination

utils.pagination.py

class LimitPagination(LimitOffsetPagination):
    '''需要我们规定:从第几条开始找,向后找多少条limit'''

    default_limit = 1               # 向后找几条的默认配置
    limit_query_param = "limit"     # 请求参数中的limit参数名
    offset_query_param = "offset"   # 请求参数中的offset参数名
    max_limit = 3                   # 最大的寻找条数

说明:参数的请求方法同上,get获取。

views.py

from utils.pagination import LimitPagination

class BookView(APIView):
    def get(self, request):
        book_list = Book.objects.all().order_by("id")

        # 实例化分页器对象
        pageObj = LimitPagination()  #  LimitOffsetPagination
        # 调用分页方法
        page_query = pageObj.paginate_queryset(book_list, request, view=self)
        # 序列化器 many表示取出多条数据
        ret = BookSeriallzer(page_query, myFields="__all__", many=True) 
        print(ret)
    
        resIO = pageObj.get_paginated_response(ret.data) # 获取分页的结果,将分页后的结果数据与Response封装在一起
        # 将数据分为count,next,prev,result。分别是数据总量,上一页/下一页的请求地址,本页的数据

        return resIO

CursorPagination

游标分页。有时候,别人能够根据你的请求参数推断出你的数据库中有多少条数据,有些公司觉得这不够安全。使用次分页方式可以将游标进行加密,使人无法获知数据的数目。

特点:

  1. 分页前必须要排序
  2. 游标加密,不允许导航到任意位置(基于前两种的分页可以通过传参,对任意的页数发起请求,游标分页不允许),只能"next"和“prev”
  3. 支持非常大的数据集。如果表中有非常大的数据量,基于偏移的分页器效率变得很低,但基于游标分页的效率高。

utils/pagination.py

class CurPagination(CursorPagination):
    '''游标分页'''
    cursor_query_param = "cursor" # 游标请求参数,相当于page页数,但该数据是加密的,来自于上次分页返回
    page_size = 2 # 默认每页显示的
    ordering = "-id" # 排序 根据id倒序
    max_page_size = 10 # 每页显示的最大条数

views.py

同上☝

posted @ 2019-10-10 10:52  学霸初养成  阅读(1277)  评论(0编辑  收藏  举报