drf 分页组件
组件导入
在drf
中,拥有三种分页器,以下是三种分页器的导入:
from rest_framework.pagination import PageNumberPagination
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.pagination import CursorPagination
第一种分页器非常常用,拥有上一页下一页,同时也可以做诸如1,2,3,4这样的跳转页数。
第二种分页器是游标分页器,它有一个基准点,你可以根据这个基准点进行左偏移和右偏移,相对使用较少。
第三种分页器效率是最高的,只有上一页和下一页,不可以做页数的跳转。
使用方式
通用声明
只需要在你的视图类中进行赋值即可。
from rest_framework.generics import ListAPIView
from rest_framework.pagination import PageNumberPagination
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.pagination import CursorPagination
from app01.serializer import *
from app01 import models
class BookAPI(ListAPIView):
queryset = models.Book.objects.filter(delete_status=False) # 查询未删除的数据
serializer_class = BookModelSerializer
pagination_class = PageNumberPagination # 指定分页器
全局配置
在全局的settings.py
下配置每页显示的个数:
#settings.py
REST_FRAMEWORK={
'PAGE_SIZE': 2, # 每页显示的个数
}
详细配置
如果需要针对不同的组件配置不同的设置,可以使用一个类来进行继承上面的分页组件,然后写详细的配置,如:
from app01.serializer import *
from app01 import models
class MyPage(PageNumberPagination):
page_size = 3 # 每页条数
page_query_param = 'page' # url上跳转的的名称,默认为page
page_size_query_param = 'size' # 每一页显示的条数(前端可通过这个获取,覆盖后端给的固定条数),如后端给三条,前端请求时在url后带上size=9就代表老铁我要九条
max_page_size = 5 # 每页最大显示条数
class BookAPI(ListAPIView):
queryset = models.Book.objects.filter(delete_status=False) # 查询未删除的数据
serializer_class = BookModelSerializer
pagination_class = MyPage
ListAPIView
分页只在获取所有时使用,所以我们直接使用generices
下的ListAPIView
。
from rest_framework.generics import ListAPIView
from rest_framework.pagination import PageNumberPagination
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.pagination import CursorPagination
from app01.serializer import *
from app01 import models
class MyPage(PageNumberPagination):
page_size = 3 # 每页条数
page_query_param = 'page' # url上跳转的的名称,默认为page
page_size_query_param = 'size' # 每一页显示的条数(前端可通过这个获取,覆盖后端给的固定条数),如后端给三条,前端请求时在url后带上size=9就代表老铁我要九条
max_page_size = 5 # 每页最大显示条数
class BookAPI(ListAPIView):
queryset = models.Book.objects.filter(delete_status=False) # 查询未删除的数据
serializer_class = BookModelSerializer
pagination_class = MyPage
APIView
如果你是使用APIView
,则配置相对比较麻烦,如下示例:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.pagination import CursorPagination
from app01.serializer import *
from app01 import models
class MyPage(PageNumberPagination):
page_size = 3 # 每页条数
page_query_param = 'page' # url上跳转的的名称,默认为page
page_size_query_param = 'size' # 每一页显示的条数(前端可通过这个获取,覆盖后端给的固定条数),如后端给三条,前端请求时在url后带上size=9就代表老铁我要九条
max_page_size = 5 # 每页最大显示条数
class BookAPI(APIView):
def get(self, request, *args, **kwargs):
book_list = models.Book.objects.all().order_by("pk") # 使用APIView时,手动排序,否则会抛出warning
# 实例化得到一个分页器对象
page_cursor = MyPage()
book_list = page_cursor.paginate_queryset(book_list, request, view=self)
next_url = page_cursor.get_next_link()
prev_url = page_cursor.get_previous_link()
book_ser = BookModelSerializer(book_list, many=True)
res_data = {
"next_url": next_url,
"prev_url": prev_url,
"data": book_ser.data
}
return Response(data=res_data)
返回格式
PageNumberPagination
使用案例:
from rest_framework.generics import ListAPIView
from rest_framework.pagination import PageNumberPagination
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.pagination import CursorPagination
from app01.serializer import *
from app01 import models
class MyPage(PageNumberPagination):
page_size = 3 # 每页条数
page_query_param = 'page' # url上跳转的的名称,默认为page
page_size_query_param = 'size' # 每一页显示的条数(前端可通过这个获取,覆盖后端给的固定条数),如后端给三条,前端请求时在url后带上size=9就代表老铁我要九条
max_page_size = 5 # 每页最大显示条数
class BookAPI(ListAPIView):
queryset = models.Book.objects.filter(delete_status=False) # 查询未删除的数据
serializer_class = BookModelSerializer
pagination_class = MyPage
它的返回格式如下:
{
"count": 17, # 代表后端还剩多少数据
"next": "http://127.0.0.1:8000/api/books/?page=4",
"previous": "http://127.0.0.1:8000/api/books/?page=2",
"results": [
{},
{},
{},
]
}
LimitOffsetPagination
使用案例:
from rest_framework.generics import ListAPIView
from rest_framework.pagination import PageNumberPagination
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.pagination import CursorPagination
from app01.serializer import *
from app01 import models
class MyPage(LimitOffsetPagination):
default_limit = 3 # 每页条数
limit_query_param = 'limit' # 往后拿几条
offset_query_param = 'offset' # 标杆
max_limit = 5 # 每页最大几条
class BookAPI(ListAPIView):
queryset = models.Book.objects.filter(delete_status=False) # 查询未删除的数据
serializer_class = BookModelSerializer
pagination_class = MyPage
返回格式如下:
{
"count": 17,
"next": "http://127.0.0.1:8000/api/books/?limit=3&offset=6&page=3",
"previous": "http://127.0.0.1:8000/api/books/?limit=3&page=3",
"results": [
{},
{},
{},
]
}
CursorPagination
使用它的性能最高。但是只适用于数据量非常大的时候使用。
使用案例:
from rest_framework.generics import ListAPIView
from rest_framework.pagination import PageNumberPagination
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.pagination import CursorPagination
from app01.serializer import *
from app01 import models
class MyPage(CursorPagination):
cursor_query_param = 'cursor' # 每一页查询的key
page_size = 2 # 每页显示的条数
ordering = 'pk' # 排序字段
class BookAPI(ListAPIView):
queryset = models.Book.objects.filter(delete_status=False) # 查询未删除的数据
serializer_class = BookModelSerializer
pagination_class = MyPage
返回格式:
{
"next": "http://127.0.0.1:8000/api/books/?cursor=cD0xOQ%3D%3D",
"previous": null,
"results": [
{},
{},
{},
]
}