分页简介
当数据量特别大的时候,我们通过API获取数据会非常慢,所以此时我们需要将数据"分批次"取出来,这里的"分批次"就是,分页!
REST框架支持自定义分页风格,你可以修改每页显示数据集合的最大长度。
分页链接支持以下两种方式提供给用户:
- 分页链接是作为响应内容提供给用户
- 分页链接被包含在响应头中(Content-Range或者Link)
内建风格使用作为响应内容提供给用户。这种风格更容易被使用可浏览API的用户所接受。
- 如果使用通用视图或者视图集合。系统会自动帮你进行分页。
- 如果使用的是APIView,你就需要自己调用分页API,确保返回一个分页后的响应。
可以将pagination_class设置为None关闭分页功能。
rest-framework自带的分页方式有三种:
其中BasePagination不是分页方式,只是定义了几个基础功能。
分页方式
1、PageNumberPagination
顾名思义:页码分页,通过页码对结果进行分页。我们可以指定显示第几页,每页显示多少条数据。
"""
A simple page number based style that supports page numbers as
query parameters. For example:
http://api.example.org/accounts/?page=4
http://api.example.org/accounts/?page=4&page_size=100
"""
2、LimitOffsetPagination
顾名思义:偏移值分页。通过设置数据的偏移值来进行分页。比如指定偏移值为100,则数据从101条开始获取,同时可以指定每页限制显示多少条数据。
"""
A limit/offset based style. For example:
http://api.example.org/accounts/?limit=100
http://api.example.org/accounts/?offset=400&limit=100
"""
3、CursorPagination
顾名思义:游标分页。游标分页预示着分页方式非常复杂。
"""
The cursor pagination implementation is necessarily complex.
For an overview of the position/offset style we use, see this post:
https://cra.mr/2011/03/08/building-cursors-for-the-disqus-api
"""
1、PageNumberPagination(页码分页)
定义分页类
class StandardResultsSetPagination(PageNumberPagination):
# 默认每页显示的数据条数
page_size = 1
# 获取URL参数中设置的每页显示数据条数
page_size_query_param = 'page_size'
# 获取URL参数中传入的页码key
page_query_param = 'page'
# 最大支持的每页显示的数据条数
max_page_size = 3
2、LimitOffsetPagination(偏移分页)
定义分页类
class StandardResultsSetPagination(LimitOffsetPagination):
# 默认每页显示的数据条数
default_limit = 2
# URL中传入的显示数据条数的参数
limit_query_param = 'limit'
# URL中传入的数据位置的参数
offset_query_param = 'offset'
# 最大每页显得条数
max_limit = 3
3、CursorPagination(游标分页)
定义分页类
class StandardResultsSetPagination(CursorPagination):
# URL传入的游标参数
cursor_query_param = 'cursor'
# 默认每页显示的数据条数
page_size = 3
# URL传入的每页显示条数的参数
page_size_query_param = 'page_size'
# 每页显示数据最大条数
max_page_size = 5
# 根据ID从大到小排列
ordering = "id"
应用
视图层面应用
视图层面有两种方式:
- APIView
- ModelView
1、APIView方式
APIView方式,我们需要自己在get方法中对queryset进行手动分页,实现如下:
class PublishView(APIView):
def get(self, request):
# restframework
# 取数据
# print("request.data", request.data)
# print("request.data type", type(request.data))
# print(request._request.GET)
# print(request.GET)
# 序列化
# 方式1:
# publish_list=list(Publish.objects.all().values("name","email"))
# 方式2:
# from django.forms.models import model_to_dict
# publish_list=Publish.objects.all()
# temp=[]
# for obj in publish_list:
# temp.append(model_to_dict(obj))
# 方式3:
# from django.core import serializers
# ret=serializers.serialize("json",publish_list)
# 序列组件
publish_list = Publish.objects.all()
#分页初始化
paginator = StandardResultsSetPagination()
#将queryset进行分页
page_publish_list = paginator.paginate_queryset(publish_list, self.request, view=self)
#将分页后的数据进行序列化
ps = PublishModelSerializers(page_publish_list, many=True)
#通过rest-framework的响应器返回数据
response = paginator.get_paginated_response(ps.data)
#return response #包含上一页,下一页的返回方式
#不包含上一页、下一页的返回方式
return Response(ps.data)
2、ModelView方式
class AuthorModelView(viewsets.ModelViewSet):
authentication_classes = [TokenAuth, ]
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
pagination_class = StandardResultsSetPagination
应用层面应用
应用层面也有两种方式:
- 局部应用
- 全局应用
1、局部应用
utils.py
class StandardResultsSetPagination(CursorPagination):
# URL传入的游标参数
cursor_query_param = 'cursor'
# 默认每页显示的数s据条数
page_size = 1
# URL传入的每页显示条数的参数
page_size_query_param = 'page_size'
# 每页显示数据最大条数
max_page_size = 5
# 根据ID从大到小排列
ordering = "id"
注意:page_size=1
自定义分页类,继承StandardResultsSetPagination:
class AuthorModelView(viewsets.ModelViewSet):
class Mypaginations(StandardResultsSetPagination):
page_size = 3
authentication_classes = [TokenAuth, ]
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
pagination_class = Mypaginations
2、全局应用
全局定义page_size:
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.utils.TokenAuth",],
"DEFAULT_PERMISSION_CLASSES": ["app01.utils.SVIPPermission", ],
'DEFAULT_PAGINATION_CLASS': 'app01.utils.StandardResultsSetPagination',
'PAGE_SIZE': 2,
}
函数内不定义page_size:
class StandardResultsSetPagination(CursorPagination):
# URL传入的游标参数
cursor_query_param = 'cursor'
# 默认每页显示的数s据条数
#page_size = None
# URL传入的每页显示条数的参数
page_size_query_param = 'page_size'
# 每页显示数据最大条数
max_page_size = 5
# 根据ID从大到小排列
ordering = "id"
views.py
class AuthorModelView(viewsets.ModelViewSet):
authentication_classes = [TokenAuth, ]
queryset = Author.objects.all()
serializer_class = AuthorModelSerializers
pagination_class = StandardResultsSetPagination
效果图: