drf提供了三个内置分页器,根据前端需求选择使用。
全局配置
在配置文件中设置全局的分页方式,如:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100 # 每页数目
}
也可通过继承内置的分页器类自定义Pagination类,来为视图添加不同分页器。在视图中通过pagination_clas
属性来指明。
class LargeResultsSetPagination(PageNumberPagination):
page_size = 10
page_query_param = 'page'
page_size_query_param = 'size'
max_page_size = 30
class BookDetailView(RetrieveAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
pagination_class = LargeResultsSetPagination # 局部指定使用分页器
注意:视图内局部设置不使用分页器
pagination_class = None
内置分页器的使用有两种方式,
- 一种是直接使用内置的,在全局配置分页器的属性参数,控制分页的效果。
- 一种是继承内置的分页器类,在继承的子类中设置分页器的属性参数,控制分页效果。
上述配置方式适用于内置的即继承内置的所有分页器的使用。需要注意的是基于APIView
的视图需要自己手动添加分页器对象;基于ListAPIView
的视图(继承GenericAPIView和视图插件的视图类以及视图集合类都可使用)仅通过参数pagination_class
配置分页器即可使用。
PageNumberPagination
前端访问网址形式:
GET http://127.0.0.1:8000/students/?page=4
可以在子类中定义的属性:
- page_size 每页数目
- page_query_param 前端发送的页数关键字名,默认为”page”
- page_size_query_param 前端发送的每页数目关键字名,默认为None
- max_page_size 前端最多能设置的每页数量
# APIView
from rest_framework.pagination import PageNumberPagination
# 一 基本使用:url=url=http://127.0.0.1:8000/pager/?page=2&size=3,size无效
class Pager(APIView):
def get(self,request,*args,**kwargs):
# 获取所有数据
ret=models.Book.objects.all()
# 创建分页对象
page=PageNumberPagination()
# 在数据库中获取分页的数据
page_list=page.paginate_queryset(ret,request,view=self)
# 对分页进行序列化
ser=BookSerializer1(instance=page_list,many=True)
return Response(ser.data)
# 二 自定制分页器类, url=http://127.0.0.1:8000/pager/?page=2&size=3
# size=30,无效,最多5条
class Mypage(PageNumberPagination):
page_size = 2
page_query_param = 'page'
page_size_query_param = 'size' # 定制传参
max_page_size = 5 # 每页最大的数据量
class Pager(APIView):
def get(self,request,*args,**kwargs):
ret=models.Book.objects.all()
page=Mypage() # 创建分页对象
page_list=page.paginate_queryset(ret,request,view=self) # 在数据库中获取分页的数据
ser=BookSerializer1(instance=page_list,many=True) # 对分页进行序列化
# return Response(ser.data)
# 这个也是返回Response对象,但是比基本的多了上一页,下一页,和总数据条数(了解即可)
return page.get_paginated_response(ser.data)
# ListAPIView
# 声明分页的配置类,即可使用
from rest_framework.pagination import PageNumberPagination
class StandardPageNumberPagination(PageNumberPagination):
page_size = 2
page_size_query_param = "size"
max_page_size = 10
page_query_param = "p"
class StudentAPIView(ListAPIView):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
pagination_class = StandardPageNumberPagination
# 127.0.0.1/four/students/?p=1&size=5
LimitOffsetPagination
前端访问网址形式:
GET http://127.0.0.1/four/students/?limit=100&offset=400
可以在子类中定义的属性:
- default_limit 默认限制,默认值与
PAGE_SIZE
设置一直 - limit_query_param limit参数名,默认’limit’
- offset_query_param offset参数名,默认’offset’
- max_limit 最大limit限制,默认None
# APIView
# http://127.0.0.1:8000/pager/?offset=4&limit=3
from rest_framework.pagination import LimitOffsetPagination
# 也可以自定制,同简单分页
class Pager(APIView):
def get(self,request,*args,**kwargs):
# 获取所有数据
ret=models.Book.objects.all()
# 创建分页对象
page=LimitOffsetPagination()
# 在数据库中获取分页的数据
page_list=page.paginate_queryset(ret,request,view=self)
# 对分页进行序列化
ser=BookSerializer1(instance=page_list,many=True)
# return page.get_paginated_response(ser.data)
return Response(ser.data)
#ListAPIView
from rest_framework.pagination import LimitOffsetPagination
class StandardLimitOffsetPagination(LimitOffsetPagination):
# 默认每一页查询的数据量,类似上面的page_size
default_limit = 2
limit_query_param = "size"
offset_query_param = "start"
class StudentAPIView(ListAPIView):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
# 调用页码分页类
# pagination_class = StandardPageNumberPagination
# 调用查询偏移分页类
pagination_class = StandardLimitOffsetPagination
CursorPagination
这种分页方式只有上一页和下一页,不能跳跃切换页面,但是查询效率极高。
前端访问网址形式:
GET http://127.0.0.1/four/students/?cursor=cD0xNQ%3D%3D
可以在子类中定义的属性:
- cursor_query_param:默认查询字段,不需要修改
- page_size:每页数目
- ordering:按什么排序,需要指定,逆序在字段前加负号:
ordering='-id'
#APIView
from rest_framework.pagination import CursorPagination
# 看源码,是通过sql查询,大于id和小于id
class Pager(APIView):
def get(self,request,*args,**kwargs):
# 获取所有数据
ret=models.Book.objects.all()
# 创建分页对象
page=CursorPagination()
page.ordering='nid'
# 在数据库中获取分页的数据
page_list=page.paginate_queryset(ret,request,view=self)
# 对分页进行序列化
ser=BookSerializer1(instance=page_list,many=True)
# 可以避免页码被猜到
return page.get_paginated_response(ser.data)
# ListAPIView
class MyCursorPagination(CursorPagination):
page_size=2
ordering='-id'
from rest_framework.generics import ListAPIView
class AuthorListView(ListAPIView):
serializer_class = serializers.AuthorModelSerializer
queryset = models.Author.objects.filter(is_delete=False)
pagination_class =MyCursorPagination