- 普通分页:看第几页,每页显示多少条数据
- 基于偏移量分页,在某个位置,向后查看多少条数据(offset limit)
- 游标分页,加密分页,只能看上一页和下一页,记录当前id的最大值和最小值
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)
效果:
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。
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
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)