解决django rest-framework page_size无效问题

项目使用rest-framework框架,全局设置后接口返回记录数与预期不符。分析page类源码发现,page_size_query_param默认值为None,导致设置的page_size不起作用,需重写分页类。还发现不设置max_page_size时,请求的page_size会生效,设置后返回结果正常,认为默认赋值存在问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目里使用了rest-framework框架,并在settings里做了下面的全局设置

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

在调用接口的时候,

http://localhost:9090/api/cluste/?page_size=500

接口并没有返回500条数据(库里有超过500条数据),而是返回来10条记录,这就跟我想要的结果有所不同了,看一下page类的源码。

class PageNumberPagination(BasePagination):
    """
    A simple page number based style that supports page numbers as
    query parameters. For example:

    http://api.example.org/accounts/?page=4
    http://api.example.org/accounts/?page=4&page_size=100
    """
    # The default page size.
    # Defaults to `None`, meaning pagination is disabled.
    page_size = api_settings.PAGE_SIZE
    
    # Client can control the page using this query parameter.
    page_query_param = 'page'

    # Client can control the page size using this query parameter.
    # Default is 'None'. Set to eg 'page_size' to enable usage.
    page_size_query_param = None

    # Set to an integer to limit the maximum page size the client may request.
    # Only relevant if 'page_size_query_param' has also been set.
    max_page_size = None

page_size_query_param : 一个字符串值,指定查询参数的名称,允许客户端根据每个请求设置页面大小。默认为 None,表示客户端可能无法控制所请求的页面大小。
max_page_size : 一个数字值,表示允许的最大页面大小。该属性仅在 page_size_query_param 也被设置时有效。

而这里 page_size_query_param 的默认值是None,并不是“page_size”,所以无论“page_size”是500,是1000,都是不起作用的,那么问题就找到了,我们需要重写一个分页类

from rest_framework.pagination import PageNumberPagination

class GlobalPageNumberPagination(PageNumberPagination):
    def __init__(self):
        super(GlobalPageNumberPagination, self).__init__()
        self.page_size_query_param = 'page_size'
        self.max_page_size = 100  # 这个设置很重要
 
 settings.py里改成
 'DEFAULT_PAGINATION_CLASS': 'lib.pagination.GlobalPageNumberPagination',

这里还发现一个问题,如果在上面的类里不设置 self.max_page_size = 100的话,我的请求page_size=500时,接口是会给我返回500条记录,这是不对的,settings里的’MAX_PAGE_SIZE’: 100 是无效的么?
于是我在GlobalPageNumberPagination类里设置了self.max_page_size = 100,我再次请求page_size=500时,接口返回给我100条的记录了,这是正确的返回。

所以我觉得rest-framework 的PageNumberPagination类里的 page_size_query_param = None 的设置是一个错误的默认赋值,应该默认设置成 page_size_query_param = ‘page_size’,如果开发者不适用page_size的话,可以自己去重写PageNumberPagination类

### Django REST framework介绍 Django REST framework (DRF) 是一个用于构建 Web API 的高级、简洁且易于使用的 Python 库,其基于著名的 Web 框架 Django 创建而成[^3]。 DRF 提供了一系列强大的工具和约定,旨在简化 HTTP 请求和响应的处理过程,并能够方便地将数据序列化为 JSON 格式。 #### 主要功能 - **资源定义(Resources)**:允许开发者清晰地定义应用程序中的各种资源及其交互方式。 - **视图集(ViewSets)**:提供了更加模块化的接口设计方法,使得操作逻辑与 URL 路由之间的映射更为直观简单[^5]。 - **序列化器(Serializers)**:负责把复杂的数据库模型实例转换成原生 Python 数据类型以便进一步渲染成 JSON 或其他格式;同时也支持反向解析输入的数据并将其保存回数据库中。 - **认证和授权**:内置多种认证机制(如基本认证、令牌认证),并且可以通过自定义类轻松扩展新的认证方式。此外还具备完善的权限控制系统,确保只有经过适当授权的用户才能访问特定资源或执行某些动作[^4]。 - **分页和过滤**:除了默认提供的简单分页外,还可以借助第三方库 `django-filter` 实现复杂条件下的记录筛选功能[^1]。 ```python from rest_framework.pagination import PageNumberPagination from django_filters.rest_framework import DjangoFilterBackend class StandardResultsSetPagination(PageNumberPagination): page_size = 10 page_size_query_param = 'page_size' max_page_size = 100 class ExampleViewSet(viewsets.ModelViewSet): queryset = YourModel.objects.all() serializer_class = YourSerializer pagination_class = StandardResultsSetPagination filter_backends = [DjangoFilterBackend] filterset_fields = ['field_name'] ``` 通过上述特性组合应用,DRF 成为了开发人员用来快速搭建高性能 RESTful APIs 的理想选择之一。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值