Django REST Framework 之基于游标、偏移量的分页

64 篇文章 0 订阅
54 篇文章 0 订阅

分页方式

  1. 普通分页:看第几页,每页显示多少条数据
  2. 基于偏移量分页,在某个位置,向后查看多少条数据(offset limit)
  3. 游标分页,加密分页,只能看上一页和下一页,记录当前id的最大值和最小值

普通分页:PageNumberPagination

from filelibrary_sourcegroup.serializers import user
from rest_framework.response import Response

from rest_framework.pagination import PageNumberPagination
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.pagination import CursorPagination



class UserInfo(APIView):

    def get(self, request):
        users = ReviewUserInfo.objects.all().order_by("id")
        pg = PageNumberPagination()
        q = pg.paginate_queryset(users, request, self)
        ser = user.UserSerializer(q, many=True)

        return pg.get_paginated_response(ser.data)

重写普通分页,使可配置:

class MyPageNumberPagination(PageNumberPagination):
	# 每页默认数量
    page_size = 2
    # 页码参数
    page_query_param = 'page'
    # 指定最大数量的参数
    page_size_query_param = "page_size"
    # 每页最大数量
    max_page_size = 4


class UserInfo(APIView):

    def get(self, request):
        users = ReviewUserInfo.objects.all().order_by("id")
        pg = MyPageNumberPagination()
        q = pg.paginate_queryset(users, request, self)
        ser = user.UserSerializer(q, many=True)
		
		# 使用 get_paginated_response 会带有count、next 等参数
        return pg.get_paginated_response(ser.data)

效果:
在这里插入图片描述

基于偏移量分页:LimitOffsetPagination

class UserInfo(APIView):

    def get(self, request):
        users = ReviewUserInfo.objects.all().order_by("id")
        pg = LimitOffsetPagination()
        q = pg.paginate_queryset(users, request, self)
        ser = user.UserSerializer(q, many=True)

        return pg.get_paginated_response(ser.data)

重写偏移量分页,使可配置:

class MyLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 2
    limit_query_param = 'limit'
    offset_query_param = 'offset'
    max_limit = 4


class UserInfo(APIView):

    def get(self, request):
        users = ReviewUserInfo.objects.all().order_by("id")
        pg = MyLimitOffsetPagination()
        q = pg.paginate_queryset(users, request, self)
        ser = user.UserSerializer(q, many=True)

        return pg.get_paginated_response(ser.data)

效果:
limit 100 但设置的最大 limit 是 4。
在这里插入图片描述

基于游标分页:CursorPagination

class UserInfo(APIView):

    def get(self, request):
        users = ReviewUserInfo.objects.all().order_by("id")
        pg = CursorPagination()
        q = pg.paginate_queryset(users, request, self)
        ser = user.UserSerializer(q, many=True)

        return pg.get_paginated_response(ser.data)

重写游标分页,使可配置:

class MyCursorPagination(CursorPagination):
    cursor_query_param = 'cursor'
    page_size = 2
    ordering = 'id'
    page_size_query_param = "page_size"
    max_page_size = 4


class UserInfo(APIView):

    def get(self, request):
        users = ReviewUserInfo.objects.all().order_by("id")
        pg = MyCursorPagination()
        q = pg.paginate_queryset(users, request, self)
        ser = user.UserSerializer(q, many=True)

        return pg.get_paginated_response(ser.data)

效果:
在这里插入图片描述
游标分页核心逻辑:
会记录当前id的最大值和最小值,再查询时使用 orm 里面的 gt 和 lt 进行数据库层面的过滤,提高效率。

# If we have a cursor with a fixed position then filter by that.
if current_position is not None:
    order = self.ordering[0]
    is_reversed = order.startswith('-')
    order_attr = order.lstrip('-')

    # Test for: (cursor reversed) XOR (queryset reversed)
    if self.cursor.reverse != is_reversed:
        kwargs = {order_attr + '__lt': current_position}
    else:
        kwargs = {order_attr + '__gt': current_position}

    queryset = queryset.filter(**kwargs)

ModelViewSet 中使用分页

class MyCursorPagination(CursorPagination):
    cursor_query_param = 'cursor'
    page_size = 2
    ordering = 'id'
    page_size_query_param = "page_size"
    max_page_size = 4


class UserViewSet(ModelViewSet):
    queryset = models.User.objects.all()
    serializer_class = serializers.UserSerializer
    pagination_class = MyCursorPagination

配置文件中设置全局分页大小

# 权限、认证相关都需要在这里配置
REST_FRAMEWORK = {
	"DEFAULT_PAGINATION_CLASS": "自定义分页的路径,MyCursorPagination"
    "PAGE_SIZE": 2,
}

参考文献

drf 中文网:https://q1mi.github.io/Django-REST-framework-documentation/api-guide/pagination_zh/
分页 pdf 总结:https://www.xkblogs.com/usr/uploads/drfppt/27-%E5%88%86%E9%A1%B5%EF%BC%88Pagination%EF%BC%89.pdf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值