You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django Rest Framework中实现非模型枚举数据的分页?

DRF处理非模型数据的标准分页实现方案

核心问题原因

DRF的默认分页逻辑(如ListView/ListAPIView)是为模型QuerySet设计的,针对非模型数据(枚举、自定义列表)不会自动触发分页流程。仅设置pagination_class属性无法让框架自动处理分页,必须手动调用分页类的核心方法。

具体解决方案

1. 定义标准分页类

先创建符合UI库要求的自定义分页类,继承DRF的PageNumberPagination:

from rest_framework.pagination import PageNumberPagination

class StandardPagination(PageNumberPagination):
    page_size = 10  # 默认每页数量
    page_size_query_param = 'page_size'  # 允许客户端通过参数自定义每页数量
    max_page_size = 100  # 限制最大每页数量

2. 使用ApiView手动实现分页

如果选择ApiView作为基类,需要手动实例化分页类、执行分页逻辑并返回标准格式响应:

from rest_framework.views import APIView
from rest_framework.response import Response

# 示例枚举数据
MY_ENUM_OPTIONS = [
    {"id": 1, "label": "选项A"},
    {"id": 2, "label": "选项B"},
    {"id": 3, "label": "选项C"},
    # ... 更多枚举项
]

class EnumListAPIView(APIView):
    pagination_class = StandardPagination

    def get(self, request):
        # 初始化分页器
        paginator = self.pagination_class()
        # 对枚举列表执行分页(支持任何可切片的序列,不限于QuerySet)
        paginated_data = paginator.paginate_queryset(MY_ENUM_OPTIONS, request)
        # 返回带count/next/previous/results的标准分页响应
        return paginator.get_paginated_response(paginated_data)

3. 使用GenericAPIView简化实现

如果使用GenericAPIView(或基于它的ListAPIView),可以利用框架内置的分页方法:

from rest_framework.generics import GenericAPIView
from rest_framework.response import Response

class EnumListGenericView(GenericAPIView):
    pagination_class = StandardPagination

    def get(self, request):
        data = MY_ENUM_OPTIONS
        # 调用框架内置的分页方法
        paginated_data = self.paginate_queryset(data)
        
        if paginated_data is not None:
            # 分页生效时返回标准格式
            return self.get_paginated_response(paginated_data)
        # 数据量不足一页时,手动构造标准格式响应
        return Response({
            "count": len(data),
            "next": None,
            "previous": None,
            "results": data
        })

4. 基于ListAPIView的实现

若使用ListAPIView,需重写get_queryset方法返回枚举列表(不能直接赋值queryset属性,因为框架默认期望它是DjangoQuerySet对象):

from rest_framework.generics import ListAPIView

class EnumListView(ListAPIView):
    pagination_class = StandardPagination

    def get_queryset(self):
        # 返回枚举列表,框架会自动触发分页逻辑
        return MY_ENUM_OPTIONS

常见错误排查

  • ApiView未手动触发分页:仅设置pagination_class属性无效,必须手动实例化分页器并调用paginate_queryset和get_paginated_response。
  • ListAPIView直接赋值queryset:若直接写queryset = MY_ENUM_OPTIONS,框架会因类型不匹配跳过分页逻辑,需通过get_queryset方法返回数据。
  • 分页类未正确继承:确保自定义分页类继承自DRF提供的分页基类(如PageNumberPagination),而非自行实现全部逻辑。

内容的提问来源于stack exchange,提问作者Nisanio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 05:39:54