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

Django REST Framework嵌套序列化器报错:QuerySet类型对象无法JSON序列化

解决QuerySet无法JSON序列化的问题

你遇到的这个TypeError: Object of type QuerySet is not JSON serializable错误,说白了就是Python的json.dumps()根本认不出Django返回的QuerySet对象,而且你的视图代码里还有几个逻辑问题,我来帮你一步步理顺:

错误核心原因

FreeTime.objects.all().values()返回的是Django特有的QuerySet对象,不是原生Python的可序列化类型(比如列表、字典),所以json.dumps()直接处理它就会报错。而且你手动拼接字典再转JSON的操作完全多余,DRF的序列化器本来就可以帮你搞定这一切。

修正后的完整代码

首先你的序列化器部分没问题,直接保留:

class UsersInfoSeriliazerByUsers(serializers.ModelSerializer):
    class Meta:
        model = FreeTime
        fields = '__all__'

class SetTimeZoneSerializer(serializers.Serializer):
    TIMEZONES = tuple(zip(pytz.all_timezones, pytz.all_timezones))
    meeting_date = serializers.DateField(format="%d-%m-%Y", input_formats= ['%d-%m-%Y', 'iso-8601'])
    time_zone_destination = serializers.ChoiceField(choices=TIMEZONES)
    time_table = UsersInfoSeriliazerByUsers(many=True, read_only=True)

然后是彻底修正后的视图方法:

from rest_framework.response import Response
from rest_framework import status

@action(detail=False, methods=['post'])
def common(self, request):
    # 先验证前端传入的请求数据
    serializer = SetTimeZoneSerializer(data=request.data)
    if serializer.is_valid():
        # 从验证后的数据里取字段(比直接用data更靠谱,已经是转换后的数据类型)
        meeting_date = serializer.validated_data['meeting_date']
        time_zone_destination = serializer.validated_data['time_zone_destination']
        
        # 这里可以根据业务需求过滤FreeTime,比如按meeting_date筛选,暂时用all()示例
        free_time_list = FreeTime.objects.all()
        
        # 拼接要返回的完整数据结构
        response_data = {
            'meeting_date': meeting_date,
            'time_zone_destination': time_zone_destination,
            'time_table': free_time_list
        }
        
        # 用序列化器处理完整数据,嵌套的time_table会自动用UsersInfoSeriliazerByUsers序列化
        result_serializer = SetTimeZoneSerializer(response_data)
        
        # DRF的Response会自动帮你把数据转成JSON返回
        return Response(result_serializer.data)
    
    # 如果验证失败,返回错误信息
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

关键修复点说明

  • 抛弃手动JSON序列化:完全用DRF的序列化器来处理数据,它会自动处理嵌套字段的序列化,包括把QuerySet转成可序列化的列表。
  • 用validated_data而非data:validated_data是经过DRF验证和类型转换后的正确数据(比如日期已经是datetime.date对象,不是字符串),比直接取request.data或者serializer.data更安全。
  • 正确初始化序列化器:第二次初始化的时候直接传Python字典,不需要转成JSON字符串,也不需要加many=True(因为这是单个数据对象,不是列表)。
  • 返回Response对象:DRF会自动处理JSON序列化和响应头,不需要手动调用json.dumps()。

备选方案(如果你非要手动处理QuerySet)

如果因为某些特殊情况,你不想用DRF序列化器处理time_table,可以把QuerySet转成原生Python列表:

j['time_table'] = list(FreeTime.objects.all().values())

但这种方式不如用序列化器优雅,因为values()返回的只是简单字典列表,没办法处理模型字段的自定义逻辑、关联关系等,还是推荐用DRF的序列化器方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:57:45