Django Rest Framework 3.7.7无法处理外键空值问题咨询
解决Django Rest Framework中外键为Null时的序列化报错问题
嘿,我完全懂你碰到的这个坑!咱们先拆解一下问题出在哪,再给你几个可行的解决方案。
问题根源
你在序列化器里给unit字段设置了source='unit.name',这意味着序列化时会尝试读取obj.unit.name的值。但当unit为Null(也就是数据库里这个外键字段是空的)时,obj.unit是None,这时候访问None.name自然会触发AttributeError——哪怕你加了allow_null=True也没用,因为这个参数是控制字段本身是否允许Null值,管不了source指向的嵌套属性为空的情况。
解决方案
根据你的需求,我给你三种不同的处理方式:
1. 序列化时显示unit的name,空值返回Null
如果你就是想把unit的name序列化出来,空的时候显示Null,用SerializerMethodField是最灵活的方式:
class AssetSerializer(serializers.ModelSerializer): unit = serializers.SerializerMethodField() def get_unit(self, obj): # 先判断unit是否存在,再返回name,否则返回None return obj.unit.name if obj.unit else None class Meta: model = Asset fields = ('pk', 'unit', )
2. 序列化外键的主键,允许空值
如果你其实是想序列化外键的主键值(而不是name),那之前的source是多余的,直接去掉就好,allow_null=True就能正常生效:
class AssetSerializer(serializers.ModelSerializer): unit = serializers.PrimaryKeyRelatedField( allow_null=True, default=None, queryset=SubLocation.objects.all() ) class Meta: model = Asset fields = ('pk', 'unit', )
3. 写入用主键,读取显示name
如果你的需求是创建/更新时传主键,但读取时显示name,可以重写to_representation方法来实现双向处理:
class AssetSerializer(serializers.ModelSerializer): unit = serializers.PrimaryKeyRelatedField( allow_null=True, default=None, queryset=SubLocation.objects.all() ) def to_representation(self, instance): # 先调用父类的序列化逻辑 representation = super().to_representation(instance) # 替换unit字段的值为name(如果存在的话) if instance.unit: representation['unit'] = instance.unit.name else: representation['unit'] = None return representation class Meta: model = Asset fields = ('pk', 'unit', )
这几种方式都能解决你遇到的空值报错问题,你可以根据自己的实际业务需求选最合适的~
内容的提问来源于stack exchange,提问作者juiceb0xk
相关产品推荐
相关产品推荐

