栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

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

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

分页方式
  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)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/861378.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号