分页模式
rest framework中提供了三种分页模式:
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
全局配置
REST_FRAMEWORK = {'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination','PAGE_SIZE': 100
}
局部配置
我们可以在视图类中进行局部设置
class PublisherViewSet(ModelViewSet):queryset = models.Publisher.objects.all()serializer_class = PublisherModelSerializerpagination_class = PageNumberPagination # 注意不是列表(只能有一个分页模式)
DRF内置分页器
1、PageNumberPagination
按页码数分页,第n页,每页显示m条数据,例如:http://127.0.0.1:8000/api/article/?page=2&size=1
分页器
# 重写
class MyPageNumber(PageNumberPagination):page_size = 2 # 每页显示多少条page_size_query_param = 'size' # URL中每页显示条数的参数page_query_param = 'page' # URL中页码的参数max_page_size = None # 最大页码数限制# 如果我要的数据是第一页显示10条: http://127.0.0.1:8000/books/?size=10&page=1
# 如果我要的是第二页显示5条: http://127.0.0.1:8000/books/?size=5&page=2
# max_page_size = 8 :控制最大显示多少条如果我想第一页显示10000条,这种不合理,通过这个参数控制,最大显示8条
视图
class ArticleList(APIView):def get(self, request, *args, **kwargs):res = {"code": 0}article_list = models.Article.objects.all().order_by("id")# 分页page_obj = MyPageNumber()page_article = page_obj.paginate_queryset(queryset=article_list, request=request, view=self)ser_obj = ArticleSerializer(page_article, many=True)res["data"] = ser_obj.datareturn Response(res)
返回带页码链接的响应
class ArticleList(APIView):def get(self, request, *args, **kwargs):res = {"code": 0}article_list = models.Article.objects.all().order_by("id")# 分页page_obj = MyPageNumber()page_article = page_obj.paginate_queryset(queryset=article_list, request=request, view=self)ser_obj = ArticleSerializer(page_article, many=True)res["data"] = ser_obj.datareturn page_obj.get_paginated_response(res)
2、LimitOffsetPagination
分页,在n位置,向后查看m条数据,例如:http://127.0.0.1:8000/api/article/?offset=2&limit=2
分页器
# offset分页
class MyLimitOffset(LimitOffsetPagination):default_limit = 5 # 默认偏移的条数 5limit_query_param = 'limit' # 偏移的条数offset_query_param = 'offset' # 从哪开始偏移max_limit = 999 # 偏移的最大条数-http://127.0.0.1:8000/books/ 结果是:从1到5
-http://127.0.0.1:8000/books/?limit=7 结果是:从1到7
-http://127.0.0.1:8000/books/?limit=2&offset=6 结果是:从7到8,两条
-http://127.0.0.1:8000/books/?offset=6 结果是:从7到11,5条
视图
class ArticleList(APIView):def get(self, request, *args, **kwargs):res = {"code": 0}article_list = models.Article.objects.all().order_by("id")# 分页page_obj = MyLimitOffset()page_article = page_obj.paginate_queryset(queryset=article_list, request=request, view=self)ser_obj = ArticleSerializer(page_article, many=True)res["data"] = ser_obj.datareturn page_obj.get_paginated_response(res)
3、CursorPagination
加密分页,把上一页和下一页的id值记住
分页器
# 加密分页
class MyCursorPagination(CursorPagination):cursor_query_param = 'cursor'page_size = 1 # 每页显示的条数ordering = '-id' # 按谁排序
视图
class ArticleList(APIView):def get(self, request, *args, **kwargs):res = {"code": 0}article_list = models.Article.objects.all().order_by("id")# 分页page_obj = MyCursorPagination()page_article = page_obj.paginate_queryset(queryset=article_list, request=request, view=self)ser_obj = ArticleSerializer(page_article, many=True)res["data"] = ser_obj.data# return Response(res)return page_obj.get_paginated_response(res)