文章目录
drf 分页器组件
为什么要使用分页
我们数据表中可能会有成千上万条数据,当我们访问某张表的所有数据时,我们不太可能需要一次把所有的数据都展示出来,因为数据量很大,对服务端的内存压力比较大还有就是网络传输过程中耗时也会比较大。
通常我们会希望一部分一部分去请求数据,也就是我们常说的一页一页获取数据并展示出来。
DRF使用分页器
分页模式
rest framework中提供了三种分页模式:
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
全局配置
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 100
}
局部配置
我们可以在视图类中进行局部设置
class PublisherViewSet(ModelViewSet):
queryset = models.Publisher.objects.all() # 只有差所有才需要分页
serializer_class = PublisherModelSerializer
pagination_class = PageNumberPagination # 注意不是列表(只能有一个分页模式)
DRF内置分页器
PageNumberPagination
按页码数分页,第n页,每页显示m条数据
例如:http://127.0.0.1:8000/api/article/?page=2&size=1
分页器
class MyPageNumberPagination(PageNumberPagination):
page_size=3 #每页条数
page_query_param='aaa' #查询第几页的key, 默认是page
page_size_query_param='size' # 每一页显示的条数
max_page_size=5 # 每页最大显示条数
LimitOffsetPagination
分页,在n位置,向后查看m条数据
例如:http://127.0.0.1:8000/api/article/?offset=2&limit=2
分页器
class MyLimitOffsetPagination(LimitOffsetPagination):
default_limit = 3 # 每页条数
limit_query_param = 'limit' # 往后拿几条
offset_query_param = 'offset' # 标杆
max_limit = 5 # 每页最大几条
CursorPagination
加密分页,把上一页和下一页的id值记住,只提供上一页和下一页url,效率最高,速度最快
列如: http://127.0.0.1:8000/api/book2/?cursor=cD0xMw%3D%3D
分页器
class MyCursorPagination(CursorPagination):
cursor_query_param = 'cursor' # 每一页查询的key
page_size = 2 # 每页显示的条数
ordering = '-id' # 排序字段
视图
继承ListAPIView:
class BookView(ListAPIView):
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
# 配置分页
pagination_class = MyCursorPagination(自定义分页器)
继承APIView使用:
class BookAPIView(APIView):
book_list = models.Book.objects.all().filter(is_delete=False)
page_cursor = MyPageNumberPagination()
book_list = page_cursor.paginate_queryset(book_list, request, view=self)
next_url = page_cursor.get_next_link()
pr_url = page_cursor.get_previous_link()
book_list_ser = ser.BookModelSerializer(book_list, many=True)
return APIResponse(data=book_list_ser.data, url={"next_url": next_url, "pr_url": pr_url})