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

Django REST Framework自定义CustomPagination分页继承后不生效问题

DRF自定义分页类不生效问题原因及解决方案

问题核心原因

当前写法存在3个关键错误,导致分页未生效,和自定义分页类本身无关:

  • 错误1:错误使用多继承逻辑。DRF的分页类不是视图类的父类,不需要和APIView一起被视图继承,强行多继承会导致类属性/方法冲突,反而影响正常逻辑。
  • 错误2:pagination_class配置被注释,且原生APIView本身不支持自动触发分页逻辑,只有GenericAPIView及其子类(如ListAPIView、ModelViewSet等)才会自动识别pagination_class配置执行分页。
  • 错误3:查询全量数据后直接序列化返回,没有调用分页类的分页方法对数据集做切片、生成分页结构。

修复方案

方案1:改用GenericAPIView实现(推荐,最简洁)

视图继承GenericAPIView,配置序列化类、分页类,自动完成分页逻辑:

from rest_framework.generics import GenericAPIView

class CouponView(GenericAPIView):
    permission_classes = [AllowAny]
    queryset = Coupons.objects.all()
    serializer_class = CouponSerializer
    pagination_class = CustomPagination # 取消注释,配置自定义分页类

    def get(self,request,pk = None,*args,**kwargs):
        id = pk
        if id is not None:
            abc = self.get_object() # 用GenericAPIView自带的get_object方法,自动处理404等异常
            serializer = self.get_serializer(abc)
            return Response(serializer.data)
        else:
            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)

方案2:坚持使用原生APIView,手动调用分页逻辑

如果一定要用原生APIView,需要手动实例化分页类,执行分页逻辑:

class CouponView(APIView):
    permission_classes = [AllowAny]
    # 手动实例化自定义分页类
    pagination_class = CustomPagination()

    def get(self,request,pk = None,*args,**kwargs):
        id = pk
        if id is not None:
            abc = Coupons.objects.get(id=id)
            serializer = CouponSerializer(abc)
            return Response(serializer.data)
        else:
            queryset = Coupons.objects.all()           
            # 手动调用分页方法处理数据集
            page = self.pagination_class.paginate_queryset(queryset, request, view=self)
            if page is not None:
                serializer = CouponSerializer(page, many=True)
                return self.pagination_class.get_paginated_response(serializer.data)
            serializer = CouponSerializer(queryset, many=True)
            return Response(serializer.data,status=200)

额外优化建议

你的CustomPagination里把page_size写死为15,建议改成类属性,后续可以灵活配置:

class CustomPagination(PageNumberPagination):
    page_size = 15 # 移到类属性位置,支持全局配置或者视图里自定义修改
    def get_paginated_response(self, data):
        return Response({
            'links': {
                'next': self.get_next_link(),
                'previous': self.get_previous_link()
            },
            'count': self.page.paginator.count,
            'page_size' : self.page_size, # 动态读取类属性
            'results': data
        })

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 15:45:02