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

如何在Django ModelViewSet中调用super()方法实现分页功能

问题根因

  • 当前代码没有调用DRF内置的分页逻辑,直接将全量过滤后的查询集序列化返回,因此不会触发分页效果
  • 你没有复用ListModelMixin的list()方法自带的分页处理流程,手动实现的序列化逻辑跳过了分页步骤

实现方案

首先确认你已经配置了DRF分页规则,支持全局配置或者视图单独配置:

分页配置示例

全局配置(写在项目settings.py中):

REST_FRAMEWORK = {
    # 指定默认分页类
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    # 配置默认每页条数
    'PAGE_SIZE': 10
}

如果只想给当前视图单独配置分页,直接在视图类中指定即可:

class RecentlyViewedVideosViewSet(ResponseViewMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    queryset = RecentlyViewedVideos.objects.all()
    serializer_class = RecentlyViewedVideosSerializer
    # 单独指定当前视图的分页类,全局已配可以省略
    pagination_class = rest_framework.pagination.PageNumberPagination

代码修改(两种实现方式)

方式1:手动调用分页逻辑(适合需要高度自定义返回格式的场景)

直接修改你现有的list方法,加入分页处理步骤:

def list(self, request, **kwargs):
    # 处理过滤逻辑
    if 'learner_id' in self.kwargs:
        learner_id = self.kwargs['learner_id']
    else:
        learner_id = self.request.learner.id
    queryset = super().get_queryset().filter(learner_id=learner_id)

    # 调用分页器处理查询集
    page = self.paginate_queryset(queryset)
    if page is not None:
        serializer = self.get_serializer(page, many=True)
        # 数据放入details字段,可按需添加分页元信息
        return self.jp_response(
            s_code='HTTP_200_OK',
            data={
                "details": serializer.data,
                "total": self.paginator.page.paginator.count,
                "current_page": self.paginator.page.number,
                "total_pages": self.paginator.page.paginator.num_pages
            }
        )
    # 无分页配置时返回全量数据
    serializer = self.get_serializer(queryset, many=True)
    return self.jp_response(
        s_code='HTTP_200_OK',
        data={"details": serializer.data}
    )

方式2:复用super().list()逻辑(代码更简洁,符合DRF规范)

把过滤逻辑抽离到get_queryset方法,直接复用父类的list分页流程,再调整返回格式即可:

# 重写get_queryset做过滤,后续其他接口也能复用该规则
def get_queryset(self):
    queryset = super().get_queryset()
    if 'learner_id' in self.kwargs:
        learner_id = self.kwargs['learner_id']
    else:
        learner_id = self.request.learner.id
    return queryset.filter(learner_id=learner_id)

def list(self, request, **kwargs):
    # 调用父类list方法获取已经分页处理后的响应
    original_resp = super().list(request, **kwargs)
    # 调整返回格式,把业务数据放入details字段
    return self.jp_response(
        s_code='HTTP_200_OK',
        data={
            "details": original_resp.data.pop("results"),
            **original_resp.data # 透传剩余的分页元信息(总条数、下一页链接等)
        }
    )

注意事项

  • 如果你用的是自定义分页类,替换上述代码中的分页类为你自己的实现即可
  • 第二种方式可维护性更高,后续如果要调整过滤规则,只需要修改get_queryset方法即可,不需要改动list逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:06:04