DRF分页器(Django Restful Framework)

资料推荐

官方文档
https://q1mi.github.io/Django-REST-framework-documentation/api-guide/pagination_zh/
B站没有好的教学视频,不建议看,直接看官方文档吧。

PageNumberPagination

此分页样式接受请求查询参数中的单个数字页码。
Request:

GET https://api.example.org/accounts/?page=4

Response:

{
    "count": 1023
    "next": "https://api.example.org/accounts/?page=5",
    "previous": "https://api.example.org/accounts/?page=3",
    "results": [
       …
    ]
}

Settings:

全局设置

全局启用 PageNumberPagination 样式,请使用以下配置,并根据需要设置 PAGE_SIZE

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100
}

单视图设置(重点!)

自定义继承子类

自定义一个继承自PageNumberPagination的分页器,然后在里面设置page_size,如下:

class LargeResultsSetPagination(PageNumberPagination):
    page_size = 1000
    page_size_query_param = 'page_size' # 非必需
    max_page_size = 10000 # 非必需

重写get_paginate_by方法

如果只想用PageNumberPagination本身,那么需要通过重写get_paginate_by方法来设置page_size。

class YourView(generics.ListAPIView):
    queryset = YourModel.objects.all()
    serializer_class = YourSerializer

    # 使用官方的 PageNumberPagination 类
    pagination_class = PageNumberPagination

    # 覆盖默认的分页设置
    def get_paginate_by(self, queryset):
        return self.request.query_params.get('page_size', 5)

LimitOffsetPagination

这种分页样式反映了查找多个数据库记录时使用的语法。客户端包括“limit”和“offset”查询参数。limit指示要返回的项目的最大数目,这相当于其他样式中的 page_size。offset指示查询相对于完整的未分页项的起始位置。
Request:

GET https://api.example.org/accounts/?limit=100&offset=400

Response:

HTTP 200 OK
{
    "count": 1023
    "next": "https://api.example.org/accounts/?limit=100&offset=500",
    "previous": "https://api.example.org/accounts/?limit=100&offset=300",
    "results": [
       …
    ]
}

Settings:

全局设置

为了全局启用 LimitOffsetPagination样式,请使用以下配置:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
	'PAGE_SIZE': 10
}

ps:又是一个易错点,虽然limitoffsetpagination用的是limit,但是全局设置时还是要设置PAGE_SIZE。。

单视图设置(重点!)

自定义继承子类实现

自定义一个继承自LimitOffsetPagination的分页器,然后在里面设置limit,如下:

class CustomLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 5  # 自定义默认每页显示的数量,一定要给
    max_limit = 20  # 自定义每页显示的最大数量,非必需

重写get_paginate_by

如果只想用LimitOffsetPagination本身,那么需要通过重写get_paginate_by方法来设置limit。

from rest_framework import generics
from rest_framework.pagination import LimitOffsetPagination

class YourView(generics.ListAPIView):
    queryset = YourModel.objects.all()
    serializer_class = YourSerializer
    pagination_class = LimitOffsetPagination  # 使用 LimitOffsetPagination

    # 覆盖默认的分页设置
    def get_paginate_by(self, queryset):
        return self.request.query_params.get('limit', 10)

获取分页输出样式/具体如何使用分页器(重点!)

像是如上的

{
    "count": 1023
    "next": "https://api.example.org/accounts/?page=5",
    "previous": "https://api.example.org/accounts/?page=3",
    "results": [
       …
    ]
}
{
    "count": 1023
    "next": "https://api.example.org/accounts/?limit=100&offset=500",
    "previous": "https://api.example.org/accounts/?limit=100&offset=300",
    "results": [
       …
    ]
}

都是pagenumberpagination、limitoffsetpagination等官方分页器通过get_paginated_response返回的默认的分页样式。

具体使用如下:

class CustomLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 5  # 自定义默认每页显示的数量

class YourView(generics.ListAPIView):
    queryset = YourModel.objects.all()
    serializer_class = YourSerializer
    pagination_class = CustomLimitOffsetPagination  # 使用自定义分页类

    def get(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)  # 对查询集进行分页
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)  # 获取分页样式的响应

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

自定义分页输出样式(重写get_paginated_response方法!!重要!)

假设我们想用一个修改过的格式替换默认的分页输出样式,该格式在嵌套的“links”键中包含下一页和上一页的链接。我们就需要自定义分页器,并重写get_paginated_response方法

class CustomPagination(pagination.PageNumberPagination):
    def get_paginated_response(self, data):
        return Response({
            'links': {
               'next': self.get_next_link(),
               'previous': self.get_previous_link()
            },
            'count': self.page.paginator.count,
            'results': data
        })

最常使用场景举例

from rest_framework.pagination import LimitOffsetPagination

from utils import ThirdPartResponse


class TaskPagination(LimitOffsetPagination):
    default_limit = 5  # 自定义默认每页显示的数量,一定要给。及时后续会在请求参数中拿到limit,也一定要给

    def get_paginated_response(self, data):
        return ThirdPartResponse(data={"total": self.count, "data": data})

@action(detail=False, methods=["get"], url_path="list-by-template/(?P<template_id>.+)")
def list_by_template(self, request, template_id=None):
    """
    根据template_id过滤任务列表
    """
    if template_id is None:
        message = "template_id is required"
        logger.error(message)
        return ThirdPartResponse(result=False, message=message)
    tasks = self.queryset.filter(template_id=template_id)

    paginator = TaskPagination()
    page = paginator.paginate_queryset(tasks, request)
    if page is not None:
        serializer = self.get_serializer(page, many=True)
        return paginator.get_paginated_response(serializer.data)
    serializer = self.get_serializer(tasks, many=True)
    return Response(serializer.data)

相关推荐

  1. DRF(Django Restful Framework)

    2024-07-17 05:40:01       29 阅读
  2. Django

    2024-07-17 05:40:01       65 阅读
  3. Web框架开发-Django-

    2024-07-17 05:40:01       35 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 05:40:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 05:40:01       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 05:40:01       58 阅读
  4. Python语言-面向对象

    2024-07-17 05:40:01       69 阅读

热门阅读

  1. 速盾:DDOS攻击能使用高防CDN防御吗?

    2024-07-17 05:40:01       21 阅读
  2. 面试题 29. 顺时针打印矩阵

    2024-07-17 05:40:01       23 阅读
  3. 【python】运用Request库实现爬虫

    2024-07-17 05:40:01       22 阅读
  4. opencv—常用函数学习_“干货“_9

    2024-07-17 05:40:01       31 阅读
  5. 掌握Conda配置:如何禁用Base环境的自动激活

    2024-07-17 05:40:01       22 阅读
  6. volatile的应用

    2024-07-17 05:40:01       23 阅读
  7. MySQL 分库分表

    2024-07-17 05:40:01       26 阅读
  8. C# 文件上传总结

    2024-07-17 05:40:01       24 阅读
  9. Linux的线程

    2024-07-17 05:40:01       22 阅读
  10. Transformer模型在多任务学习中的革新应用

    2024-07-17 05:40:01       26 阅读
  11. 【Qt+opencv】ROI与图像混合

    2024-07-17 05:40:01       25 阅读
  12. Jmeter二次开发Demo

    2024-07-17 05:40:01       24 阅读