Django序列化器校验时出现KeyError: 'parent'报错如何解决?
报错原因
- 核心触发原因:当请求未提交
parent字段时(比如PATCH局部更新仅修改用户名、创建用户时未传parent参数),序列化器校验后的attrs字典不会包含parent键,直接用attrs['parent']取值就会触发KeyError。 - 隐藏问题1:
id是模型主键,DRF默认将其设为只读字段,正常业务请求不会提交id参数,attrs中同样不存在id键,修复parent的问题后下一步也会触发KeyError: 'id'。 - 隐藏问题2:
elif判断顺序错误,代码优先访问attrs['parent'].id再判断attrs['parent'] != None,如果parent实际为空会直接触发AttributeError。
修复方案
- 所有从
attrs取值的操作改用attrs.get()方法,不存在的键会默认返回None,不会抛出键错误。 - 调整判断逻辑顺序,先判断
parent是否为空,再访问parent.id属性,避免空指针报错。 - 待校验的实例id从序列化器的
self.instance属性获取(更新场景下会自动绑定当前修改的模型实例,创建场景下self.instance为None),不要从attrs中读取。 - Python最佳实践:判断空值用
is None替代== None,避免运算符重载导致的逻辑异常。
修复后代码如下:
class ModelSerializer(serializers.ModelSerializer): class Meta: model = MyModel fields = ('id','name','password','parent') def validate(self, attrs): attrs = super().validate(attrs) current_user_id = self.context['request'].user.pk # 安全获取parent字段,未传则返回None parent = attrs.get('parent') # 区分场景获取待操作的实例ID instance_id = self.instance.pk if self.instance else None # 允许用户修改自己账号时将parent设为空 if parent is None: if instance_id == current_user_id: return attrs raise ValidationError('Unauthorized Request') # 传了parent的场景,仅允许parent为当前登录用户 if parent.id != current_user_id: raise ValidationError('Unauthorized Request') return attrs
内容的提问来源于stack exchange,提问作者user14491987
相关产品推荐
相关产品推荐

