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

Django REST Framework 之基于游标、偏移量的分页,第1张

分页方式
  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

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/869752.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存