文章目录

  • Django drf 分页查询(批量查询)
  • PageNumberPagination:普通分页
  • Django 自定义分页器
  • 自定义批量查询的返回结构
  • LimitOffsetPagination:偏移分页
  • CursorPagination:游标分页 -- 速度快,但不能指定查询


Django drf 分页查询(批量查询)

REST framework提供了分页的支持
我们可以在配置文件中设置全局的分页方式,如:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS':  'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100  # 每页数目
}

也可单独为视图添加不同分页行为。在视图中通过pagination_clas属性来指明

class AssetsViewSet(ModelViewSet):
    queryset = AssetsModel.objects.all()
    permission_classes = [AllowAny]
    pagination_class = LimitOffsetPagination
    ...

也可通过自定义Pagination类,来为视图添加不同分页行为:

class LargeResultsSetPagination(PageNumberPagination):
    page_size = 1000
    page_size_query_param = 'page_size'
    max_page_size = 10000
class BookDetailView(RetrieveAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    pagination_class = LargeResultsSetPagination

注意:如果在视图内关闭分页功能,只需在视图内设置

pagination_class = None

PageNumberPagination:普通分页

前端访问网址形式:

GET  http://127.0.0.1:8000/student/?page=4

使用比较常见,前端会显示出,现在总共多少页。

Django 自定义分页器

可以在子类中定义的属性:

page_size – 每页数目
page_query_param – 前端发送的页数关键字名,默认为”page”
page_size_query_param – 允许客户端根据每个请求设置页面大小。默认为 None,表示客户端无法控制所请求的页面大小。
max_page_size – 前端最多能设置的每页数量

注意 我们自定义分页类时,一定要配置 page_size_query_param,否则它的默认值为None, 表示客户端无法控制所请求的页面大小。是由后台配置的。

from rest_framework.pagination import PageNumberPagination

class MyPageNumberPagination(PageNumberPagination):
    page_size = 3  # 每页显示3条数据
    page_query_param = 'page'  # 查询参数
    page_size_query_param = 'size'
    max_page_size = 5  # 最大每页显示五条数据

如上代码
前端请求路径:

/api/v1/asset?batch=1&batch_size=5

返回结果:

{
    "count": 4,
    "next": "http://127.0.0.1:8001/api/v1/asset/?batch=2&batch_size=5",
    "previous": null,
    "results": [
        {
            "id": 6,
            "asset_id": "773",
            "asset_type": " asset_type",
            "asset_name": "aaaaa",
            "mgmt_ip": "1.13.1.1",
            "protocol": "bbbbb",
            "tenant_id": "ggggggggg",
            "description": "sssssss"
        },
        {
            "id": 7,
            "asset_id": "494",
            "asset_type": " asset_type",
            "asset_name": "aaaaa",
            "mgmt_ip": "1.13.1.1",
            "protocol": "bbbbb",
            "tenant_id": "ggggggggg",
            "description": "sssssss"
        },
        {
            "id": 8,
            "asset_id": "171",
            "asset_type": " asset_type",
            "asset_name": "cccccccccccc",
            "mgmt_ip": "1.13.1.1",
            "protocol": "bbbbb",
            "tenant_id": "ggggggggg",
            "description": "sssssss"
        }
    ]
}

如上,是我们不复写 def list的自动返回。
如果我要自定义批量查询的返回结构呢?

自定义批量查询的返回结构

Django Rest framework 分页的使用
参考URL:

比如,这里我想删掉 count、next、previous 字段,返回格式改成:

{
  "status_code":200,
  "data": {
“result”: [
  {
  ...
  }

思路: 复写 def list方法,在里面操作获取数据,组装返回给前端的结构。 推荐阅读本标题下参考URL。

#自定义分页类
class MyPageNumberPagination(PageNumberPagination):
    #每页显示多少个
    page_size = 3
    #默认每页显示3个,可以通过传入pager1/?page=2&size=4,改变默认每页显示的个数
    page_size_query_param = "size"
    #最大页数不超过10
    max_page_size = 10
    #获取页码数的
    page_query_param = "page"


class Pager1View(APIView):
    def get(self,request,*args,**kwargs):
        #获取所有数据
        roles = models.Role.objects.all()
        #创建分页对象,这里是自定义的MyPageNumberPagination
        pg = MyPageNumberPagination()
        #获取分页的数据
        page_roles = pg.paginate_queryset(queryset=roles,request=request,view=self)
        #对数据进行序列化
        ser = PagerSerialiser(instance=page_roles,many=True)
        return Response({"status_code": 200, 'data': {'result':ser.data}})

LimitOffsetPagination:偏移分页

前端访问网址形式:

GET http://127.0.0.1/four/student/?limit=100&offset=400

这是veiw层,添加:

pagination_class = LimitOffsetPagination