Django REST Framework中序列化程序验证的顺序
情况
在Django REST Framework的验证中工作时ModelSerializer
,我注意到Meta.model
字段总是被验证,即使这样做不一定有意义。以以下示例进行User
模型的序列化:
- 我有一个创建用户的端点。因此,有一个
password
领域和一个confirm_password
领域。如果两个字段不匹配,则无法创建用户。同样,如果所请求的username
已经存在,则无法创建用户。 - 用户为上述每个字段发布了不正确的值
validate
已在序列化程序中实现的实现(请参见下文),以捕获不匹配password
和confirm_password
字段
实施validate
:
def validate(self, data): if data['password'] != data.pop('confirm_password'):
raise serializers.ValidationError("Passwords do not match")
return data
问题
即使ValidationError
通过引发了validate,ModelSerializer
仍然会查询数据库以查看username
是否已在使用。从端点返回的错误列表中可以明显看出这一点。模型和非现场误差都存在。
因此,我想知道如何在非现场验证完成之前阻止模型验证,从而节省了对数据库的调用。
尝试解决
我一直试图通过DRF的源来找出发生这种情况的位置,但是我未能成功找到需要覆盖的内容才能使它起作用。
回答:
由于你的username字段很可能已unique=True
设置,因此Django REST框架会自动添加一个验证器,该验证器将检查以确保新用户名是唯一的。实际上,你可以通过进行确认repr(serializer()
),这将向你显示所有自动生成的字段,其中包括验证程序。
验证按特定的,未记录的顺序运行
- 字段反序列化称为(
serializer.to_internal_value
和field.run_validators
) serializer.validate_[field]
被称为每个领域- 称为序列化器级别的验证器(
serializer.run_validation
后跟serializer.run_validators
) - serializer.validate
因此,你看到的问题是在序列化程序级别的验证之前调用了字段级别的验证。虽然我不建议这样做,但是你可以通过
extra_kwargs
在serilalizer的meta中进行设置来删除字段级验证器。
class Meta: extra_kwargs = {
"username": {
"validators": [],
},
}
但是,你将需要unique
在自己的验证中重新执行检查,以及已自动生成的任何其他验证器。
以上是 Django REST Framework中序列化程序验证的顺序 的全部内容, 来源链接: utcz.com/qa/427382.html