RESF framework框架-分页源码流程解析

455 阅读2分钟

分页

这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战

感激相遇 你好 我是y大壮

作者:y大壮
链接:juejin.cn/user/756923… 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

🌊🌈关于前言:

文章部分内容及图片出自网络,如有问题请与我本人联系

🌊🌈关于内容:

1 全局分页

我们可以在配置文件中设置全局的分页方式,如:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS':  'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100  # 每页数目
}

注意:如果在视图内关闭分页功能,只需在视图内设置

pagination_class = None

2 局部分页

# ***************** 分页 ********************
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
​
from . import models
​
​
class PageSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = '__all__'
​
​
class PageGroupView(APIView):
    def get(self, request, *args, **kwargs):
        roles = models.Role.objects.all()
        pg = PageNumberPagination()
        data = pg.paginate_queryset(queryset=roles,request=request,view=self)
        pg_data = PageSerializer(instance=data, many=True)
        return Response(pg_data.data)
url(r'^(?P<version>[v1|v2]+)/page1/$', views.PageGroupView.as_view()),  # 分页

3 可选分页器(自定义分页)

1) PageNumberPagination

可以在子类中定义的属性:

  • page_size 每页数目
  • page_query_param 前端发送的页数关键字名,默认为"page"
  • page_size_query_param 前端发送的每页数目关键字名,默认为None
  • max_page_size 前端最多能设置的每页数量

分页,看第n页,每页显示n条数据;

class MyPageNumberPagination(PageNumberPagination):
    """
    http://127.0.0.1:8000/api/v1/page1/?page=2
    """
    page_size = 2
    page_size_query_param = 'page_size'  # http://127.0.0.1:8000/api/v1/page1/?page=1&page_size=6 重新指定每页显示的条数
    max_page_size = 5
​
​
class PageSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = '__all__'
​
​
class PageGroupView(APIView):
    def get(self, request, *args, **kwargs):
        # 获取使用数据
        roles = models.Role.objects.all()
        # 创建分页对象
        pg = MyPageNumberPagination()
        # 在数据库中获取分页的数据
        data = pg.paginate_queryset(queryset=roles,request=request,view=self)
        # 对数据进行序列化
        pg_data = PageSerializer(instance=data, many=True)
        return Response(pg_data.data)

2)LimitOffsetPagination

可以在子类中定义的属性:

  • default_limit 默认限制,默认值与PAGE_SIZE设置一直
  • limit_query_param limit参数名,默认'limit'
  • offset_query_param offset参数名,默认'offset'
  • max_limit 最大limit限制,默认None

分页,在n个位置,向后查看n条数据;

class MyLimitOffsetPagination(LimitOffsetPagination):
    """
    http://127.0.0.1:8000/api/v1/page1/?offset=3&limit=4  # 第三页显示4条数据
    """
    default_limit = 2  # 默认为每页2条
    limit_query_param = 'limit'  # 第几页
    offset_query_param = 'offset'  # 显示几条数据
    max_limit = 5  # 最大每页5条
​
​
class PageSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = '__all__'
​
​
class PageGroupView(APIView):
    def get(self, request, *args, **kwargs):
        # 获取使用数据
        roles = models.Role.objects.all()
        # 创建分页对象
        # pg = MyPageNumberPagination()
        pg = MyLimitOffsetPagination()
        # 在数据库中获取分页的数据
        data = pg.paginate_queryset(queryset=roles, request=request, view=self)
        # 对数据进行序列化
        pg_data = PageSerializer(instance=data, many=True)
        # return Response(pg_data.data)
        return pg.get_paginated_response(pg_data.data)  # 添加一些参数

3)CursorPagination(加密分页)

加密分页,上一页和下一页

class MyCursorPagination(CursorPagination):
    """
    加密分页
    "next": "http://127.0.0.1:8000/api/v1/page1/?cursor=cD00",
    "previous": "http://127.0.0.1:8000/api/v1/page1/?cursor=cj0xJnA9Mw%3D%3D",
    """
    cursor_query_param = 'cursor'  # 查询参数
    page_size = 2  # 每页二条
    ordering = 'id'  # 以id查询  -id:表示逆序
    page_size_query_param = None  # 名称 
    max_page_size = None  # 最大条数
​
​
class PageSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = '__all__'
​
​
class PageGroupView(APIView):
    def get(self, request, *args, **kwargs):
        # 获取使用数据
        roles = models.Role.objects.all()
        # 创建分页对象
        # pg = MyPageNumberPagination()
        # pg = MyLimitOffsetPagination()
        pg = MyCursorPagination()
        # 在数据库中获取分页的数据
        data = pg.paginate_queryset(queryset=roles, request=request, view=self)
        # 对数据进行序列化
        pg_data = PageSerializer(instance=data, many=True)
        # return Response(pg_data.data)
        return pg.get_paginated_response(pg_data.data)  # 添加一些参数