DRF--分页
前戏
当我们的数据有上万条的时候,我们不可能把所有的数据都返回给前端,肯定是每页显示多少条这样的显示在前端,这样方便用户的查看。DRF提供了我们三种分页的方法,
第一种 PageNumberPagination 看第n页,每页显示n条数据,第二种 LimitOffsetPagination 在第n个位置 向后查看n条数据,第三种 CursorPagination 加密游标的分页 把上一页和下一页的id记住。
这三种方法都可以在pagination类里查看到
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
PageNumberPagination
在项目根目录下创建一个utils目录,在里面创建一个pagination.py文件,里面配置我们的分页类,类继承了PageNumberPagination类
from rest_framework import pagination class MyPaginator(pagination.PageNumberPagination): page_size = 2 # 每页显示两条 page_query_param = 'page' # 页数的参数名为page page_size_query_param = 'size' # 条数的参数为size max_page_size = 3 # 每页的条数最大不超过3条
在写我们的视图函数
from utils.pagination import MyPaginator class PageBookView(APIView): def get(self, request): queryset = Book.objects.all() # 先实例化分页器对象 page_obj = MyPaginator() # 用我自己的分页器调用分页方法进行分页 page_data = page_obj.paginate_queryset(queryset, request) # 序列化我们分页好的数据 ser_obj = BookSerializer(page_data, many=True) return Response(ser_obj.data)
访问如下的路径:http://127.0.0.1:8000/api/page_book/?page=2&size=3 表示查询第二页的数据,显示三条
这样查询出来的是没有上一页和下一页的,如果想要上一页和下一页的链接,只需要改return后面的就可以了
from utils.pagination import MyPaginator class PageBookView(APIView): def get(self, request): queryset = Book.objects.all() # 先实例化分页器对象 page_obj = MyPaginator() # 用我自己的分页器调用分页方法进行分页 page_data = page_obj.paginate_queryset(queryset, request) # 序列化我们分页好的数据 ser_obj = BookSerializer(page_data, many=True) # 给响应添加上一页和下一页链接 return page_obj.get_paginated_response(ser_obj.data)
这是我们自己写的view视图,在前几篇博客中,DRF提供了我们更简单的方法返回数据,只需要提供queryset和serializer_class就可以了,比如下面的这种
class BookModelView(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer
这样不管你是什么请求,都能处理。DRF也提供了我们分页的功能,只需要加pagination_class,后面写我们自己配置的分页类就可以了
from utils.pagination import MyPaginator class BookModelView(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer pagination_class = MyPaginator # 我们自己配置的分页类
只需要这样简单的配置一下就可以完成和上面一样的功能。
LimitOffsetPagination
LimitOffsetPagination 在第n个位置 向后查看n条数据
在我们的pagination.py文件里,在写个LimitOffsetPagination的类
from rest_framework import pagination class LimitOffsetPaginator(pagination.LimitOffsetPagination): default_limit = 1 # 默认显示的条数 limit_query_param = 'limit' # url里显示条数的参数名 offset_query_param = 'offset' # url里显示偏移位置的参数名
视图和上面的类似,只需要更改配置的分页类就可以了
from utils.pagination import LimitOffsetPaginator class PageBookView(APIView): def get(self, request): queryset = Book.objects.all() # 先实例化分页器对象 page_obj = LimitOffsetPaginator() 改这里就可以了 # 用我自己的分页器调用分页方法进行分页 page_data = page_obj.paginate_queryset(queryset, request) # 序列化我们分页好的数据 ser_obj = BookSerializer(page_data, many=True) return Response(ser_obj.data)
使用DRF的视图
from utils.pagination import LimitOffsetPaginator class BookModelView(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer pagination_class = LimitOffsetPaginator # 我们自己配置的分页类
路径:http://127.0.0.1:8000/api/book/?limit=2&offset=3,后面的参数offset表示从第3个后开始,limit表示显示两个。比如,数据库里的内容为5,6,7,8,9,则显示的为8和9
CursorPagination
CursorPagination 加密游标的分页 把上一页和下一页的id记住。
在我们的pagination.py文件里,在写个CursorPaginatior的类
from rest_framework import pagination class CursorPaginatior(pagination.CursorPagination): cursor_query_param = 'cursor' ordering = '-id' # 按id降序排 page_size = 2 # 每页显示两条
视图和上面的类似
from utils.pagination import CursorPaginatior class BookModelView(viewsets.ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer pagination_class = CursorPaginatior # 我们自己配置的分页类
总结
DRF提供我们的三种分页方法我们都已经会了,最后再看一下三种分页类的配置
from rest_framework import pagination class MyPaginator(pagination.PageNumberPagination): page_size = 2 # 每页显示两条 page_query_param = 'page' # 页数的参数名为page page_size_query_param = 'size' # 条数的参数为size max_page_size = 3 # 每页的条数最大不超过3条 class LimitOffsetPaginator(pagination.LimitOffsetPagination): default_limit = 1 # 默认显示的条数 limit_query_param = 'limit' # url里显示条数的参数名 offset_query_param = 'offset' # url里显示偏移位置的参数名 class CursorPaginatior(pagination.CursorPagination): cursor_query_param = 'cursor' ordering = '-id' # 按id降序排 page_size = 2 # 每页显示两条