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
相关产品推荐
相关产品推荐

