分页类

三种分页类使用

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
    })

posted @ 2023-04-10 09:31  codegjj  阅读(7)  评论(0)    收藏  举报