分页类
三种分页类使用
from .pages import CommonPage
class CarView(ModelViewSet):
queryset = Car.objects.all()
serializer_class = MyCarSerializer
# 注册使用
pagination_class = CommonPage
PageNumberPagination
# 导入
from rest_framework.pagination import PageNumberPagination
# 编写分页类
class CommonPage(PageNumberPagination):
# 每页显示几条数据, 写几默认就是几条。
page_size = 2
# 查询页码参数《里面写 page 前端就是 ?page=1 <number 类型>, 写 p 就是 ?p=1》
page_query_param = 'page'
# 调节显示的条数, 比如:size=4, 格式同上。但不能超过下面 max_page_size 的参数。
page_size_query_param = 'size'
# 每页最多显示几条数据(最大限制)
max_page_size = 5
# eg: 查询第 3 页的 4 条内容
http://127.0.0.1:8000/books/?page=3&size=4
LimitOffsetPagination
# 导入
from rest_framework.pagination import LimitOffsetPagination
# 编写分页类
class CommonPage(LimitOffsetPagination):
# 每页默认显示多少条
default_limit = 2
# 每页取多少条
limit_query_param = 'limit'
# 从第0个位置偏移多少开始取数据
offset_query_param = 'offset'
# 最大限制条数
max_limit = 5
# eg: 从第 2 条开始取 3 条
http://127.0.0.1:8000/books/?limit=3&offset=2
CursorPagination
""" 只能做上下页点击查看,不能选择特定页。但效率高。"""
# 导入
from rest_framework.pagination import CursorPagination
# 编写分页类
class CommonPage(CursorPagination):
# 还回两个链接,表示上一页和下一页,前端可做点击事件。
cursor_query_param = 'cursor'
# 每页显示多少条
page_size = 2
# 排序规则,必须是表中有的字段,一般用id, 也可以用别的字段。
ordering = 'id'
自定义分页器(继承APIview实现)
1. 视图类
其他文件代码参考上诉三种分页类的编写
from .models import Car
from .serializer import MyCarSerializer
from .pages import CommonPage
from rest_framework.viewsets import ViewSet
class CarView(ViewSet):
def list(self, request):
car = Car.objects.all()
# 分页类实例化的对象(自己写的哦)
paginator = CommonPage()
ps = paginator.paginate_queryset(car, request, self)
# 序列类实例化的对象(自己写的哦)
res = MyCarSerializer(instance=ps, many=True)
# 返回值类型格式
""" 第一种 """
# return Response(res.data)
""" 第二种 """
# return Response({
# 'count': car.count(),
# 'next': paginator.get_next_link(),
# 'previous': paginator.get_previous_link(),
# 'results': res.data
# })
""" 第三种 """
return paginator.get_paginated_response(res.data)
2. 分页类(源码分析)
# 1 只有查询所有才分页 ====> list
# 2 ListModelMixin 的list
class ListModelMixin:
def list(self, request, *args, **kwargs):
# 这里是过滤类
queryset = self.filter_queryset(self.get_queryset())
# 分页类 调用咱们写的分页类对象的paginate_queryset方法返回了 分页后的qs对象
page = self.paginate_queryset(queryset)
if page is not None:
# 完成序列化
serializer = self.get_serializer(page, many=True)
# get_paginated_response 实现 上一页 和 下一页 链接
return self.get_paginated_response(serializer.data)
##### 分页 结束###
serializer = self.get_serializer(queryset, many=True)
return Response(data=serializer.data)
# 4. self.paginate_queryset(queryset)
# self是视图类的对象,ListModelMixin中没有这个方法,是 GenericAPIView 的 paginate_queryset(queryset)
# 视图类的对象中没有 paginator,就不分页
def paginate_queryset(self, queryset):
if self.paginator is None:
return None
# self.paginator 到底是啥? 我们配置在视图类上的分页类的对象
# 我们写的分页类对象的 paginate_queryset 方法
return self.paginator.paginate_queryset(queryset, self.request, view=self)
# 5 self.paginator
@property
def paginator(self):
if not hasattr(self, '_paginator'):
if self.pagination_class is None:
self._paginator = None
else:
# 一开始没有,走了这句
self._paginator = self.pagination_class()
return self._paginator # 它就是我们配置的分页类的对象
# 6 self.pagination_class()
# 如果我们视图类中配置了:pagination_class = CommonPageNumberPagination
# 如果我们没配:项目自己的配置文件,drf内置的
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
定制还回格式
重写分页类的 get_paginated_response 方法,
# 源码 《然后重写它》
def get_paginated_response(self, data):
return Response({
'count': self.count,
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'results': data
})

浙公网安备 33010602011771号