DRF Serializer接收模型实例报错期望字典类型解决方案
问题修复方案
报错由两处核心代码错误导致,按以下步骤修改即可解决:
1. 修复序列化器构造方法的参数错误
你自定义的JSONAPIModelSerializer的__init__方法存在两个错误:
- 将实例方法的第一个参数错误命名为
cls(cls是类方法的约定参数名,实例方法第一个参数必须为self) - 调用父类构造方法时多余传入了
cls作为位置参数,导致初始化参数错位
原错误代码
def __init__(cls, *args, **kwargs): if kwargs.get('many', False) is True: context = kwargs.get('context', {}) context.update({'is_many': True}) kwargs.update({'context': context}) return super().__init__(cls, *args, **kwargs)
修正后代码
def __init__(self, *args, **kwargs): if kwargs.get('many', False): context = kwargs.get('context', {}) context['is_many'] = True kwargs['context'] = context super().__init__(*args, **kwargs)
2. 删除retrieve方法中多余的is_valid()调用
DRF序列化器的is_valid()仅用于反序列化场景(即处理用户提交的写入请求,校验传入的字典格式数据合法性),而查询接口属于序列化场景(将模型实例转为响应字典),实例化序列化器传入模型实例后,直接访问.data即可拿到序列化结果,不需要做校验。
你在单条查询逻辑中调用is_valid(),DRF会把传入的Anime模型实例当成用户提交的待校验数据处理,自然会抛出「期望字典类型,实际拿到Anime实例」的错误,这也是为什么list接口正常——list接口中你没有调用is_valid(),直接返回了serializer.data。
原错误代码
def retrieve(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance) if serializer.is_valid(): return Response(serializer.data) return Response(serializer.errors)
修正后代码
def retrieve(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance) return Response(serializer.data)
额外可选修正
你代码中还有两处逻辑小问题可以顺手修复:
format_object方法中type字段的判断逻辑写反,且Meta类中定义的资源名字段是resource_name不是resource_type,原代码会导致单条序列化时type字段为None
修正前:
修正后:'type': instance.__class__.__name__.lower() if not getattr(self.Meta, 'resource_type', None) else None,'type': getattr(self.Meta, 'resource_name', None) or instance.__class__.__name__.lower(),- 广播信息中的
endDate字段错误取了date_start的值,应该改为instance.date_end
内容的提问来源于stack exchange,提问作者rafael
相关产品推荐
相关产品推荐

