Django REST Framework中RelatedField的to_representation如何返回dict对象
错误产生原因
- DRF的
RelatedField内置了主键哈希优化逻辑,默认会对字段返回的序列化值做哈希校验,用于去重、唯一校验等场景。而Python中字典属于可变对象,原生不支持哈希操作,直接返回字典就会触发'dict' object is not hashable报错。 - 如果给该字段配置了
many=True、unique=True参数,会进一步触发哈希校验逻辑,提高报错概率。
解决方法
根据你的使用场景选择对应方案即可:
场景1:仅需序列化输出,不需要反序列化接收参数
直接修改继承的父类为serializers.ReadOnlyField,该字段为只读类型,不会触发哈希校验逻辑,天然支持返回字典:
class TagField(serializers.ReadOnlyField): def to_representation(self, value): resp = { 'name': value.name, 'categoryid': value.categoryid.pk } return resp
场景2:需要同时支持序列化和反序列化
保留RelatedField继承关系,做两处调整即可:
- 给自定义字段类添加
use_pk_only_optimization = False属性,关闭默认的主键哈希优化逻辑 - 实现
to_internal_value方法,完成前端传入值到对应ORM实例的转换逻辑
class TagField(serializers.RelatedField): # 关闭主键哈希优化,避免触发哈希校验 use_pk_only_optimization = False def to_representation(self, value): resp = { 'name': value.name, 'categoryid': value.categoryid.pk } return resp # 反序列化逻辑可根据自身业务调整,以下为示例 def to_internal_value(self, data): # 示例逻辑:假设前端传入tag的主键值,返回对应的Tag实例 from your_app.models import Tag return Tag.objects.get(pk=data)
补充注意:如果该字段配置了
many=True,不要给字段添加unique=True等需要做值去重、哈希校验的参数。
内容的提问来源于stack exchange,提问作者A.Mohammadi
相关产品推荐
相关产品推荐

