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

Django Viewset分页触发序列化错误,如何正确实现分页?

解决DRF ViewSet分页中的JSON序列化错误

嘿,我来帮你分析下问题所在,以及怎么解决~

你遇到的TypeError: Object of type 'Feed' is not JSON serializable错误,核心原因很明确:你直接把未经过序列化的Feed模型实例列表传给了Response。paginator.paginate_queryset返回的是原始的Model对象,而DRF的Response只能处理已经序列化后的字典/列表数据,没法直接把Model实例转成JSON。


修复你当前的自定义实现

如果你想保留自己手动处理分页逻辑的写法,只需要在返回前用你的FeedSerializer把分页后的Feed实例序列化即可:

class FeedViewSet(ModelViewSet):
    queryset = Feed.objects.all()
    serializer_class = FeedSerializer

    def list(self, request, *args, **kwargs):
        paginator = pagination.LimitOffsetPagination()
        paginator.default_limit = 15
        
        # 用ViewSet内置的get_queryset()获取查询集,更符合规范
        queryset = self.filter_queryset(self.get_queryset())
        # 执行分页
        paginated_feeds = paginator.paginate_queryset(queryset, request)
        
        # 关键步骤:用序列化器处理分页后的实例列表
        serializer = self.get_serializer(paginated_feeds, many=True)
        
        # 用分页器的get_paginated_response生成标准分页响应
        return paginator.get_paginated_response({
            'feeds': serializer.data,
            'limit': paginator.limit,
            'offset': paginator.offset,
            'overall_count': paginator.count
        })

这里做了几个优化:

  • 用self.get_queryset()替代直接调用Feed.objects.all(),方便后续扩展过滤、排序等逻辑
  • 调用self.get_serializer获取序列化器实例,传入many=True来处理列表数据
  • 用paginator.get_paginated_response生成符合DRF规范的响应,它会自动添加next/previous分页链接

更简洁的DRF标准分页实现

其实DRF的ModelViewSet已经内置了分页支持,完全不需要重写list方法,推荐用这种更规范的方式:

方式1:全局配置分页(所有ViewSet生效)

在项目的settings.py中添加DRF的全局配置:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 15  # 默认每页15条
}

配置后,所有继承ModelViewSet或ListAPIView的视图都会自动应用LimitOffset分页,无需额外代码。

方式2:单个ViewSet单独配置

如果你只想给FeedViewSet启用分页,可以直接在类中指定分页类:

class FeedViewSet(ModelViewSet):
    queryset = Feed.objects.all()
    serializer_class = FeedSerializer
    pagination_class = pagination.LimitOffsetPagination

    # 自定义默认limit值
    def get_pagination_class(self):
        pagination_cls = super().get_pagination_class()
        if pagination_cls:
            pagination_cls.default_limit = 15
        return pagination_cls

这种方式完全遵循DRF的设计理念,DRF会自动帮你完成分页查询、序列化、响应格式处理(包括返回总条数、分页链接等),代码更简洁易维护。


总结

  • 原始代码报错的本质是未序列化Model实例:必须通过DRF的Serializer把Model对象转换成Python字典,才能被Response序列化为JSON
  • 推荐使用DRF内置的分页配置方式,减少重复代码,遵循框架规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:49:38