情况
在 Django REST Framework 中进行验证时ModelSerializer
,我注意到Meta.model
字段始终经过验证,即使这样做不一定有意义。以下面的例子为例User
模型的序列化:
- 我有一个创建用户的端点。因此,有一个
password
场和一个confirm_password
场地。如果两个字段不匹配,则无法创建用户。同样,如果要求username
已存在,无法创建该用户。
- 用户为上述每个字段发布了不正确的值
- 一个实现
validate
已在序列化器中进行(见下文),捕获不匹配的password
and confirm_password
fields
实施validate
:
def validate(self, data):
if data['password'] != data.pop('confirm_password'):
raise serializers.ValidationError("Passwords do not match")
return data
Problem
即使当ValidationError
是由validate
, the ModelSerializer
仍然查询数据库来检查是否username
已在使用中。这在从端点返回的错误列表中很明显;模型误差和非现场误差都存在。
因此,我想知道如何在非字段验证完成之前阻止模型验证,从而节省对数据库的调用。
尝试解决方案
我一直在尝试查看 DRF 的源代码来找出发生这种情况的位置,但我未能成功找到需要覆盖的内容才能使其正常工作。
因为很可能你的username
场有unique=True
设置后,Django REST Framework 会自动添加一个验证器来检查以确保新用户名是唯一的。您实际上可以通过执行以下操作来确认这一点repr(serializer())
,它将向您显示所有自动生成的字段,其中包括验证器。
验证按照特定的、未记录的顺序运行
- 字段反序列化称为 (serializer.to_internal_value https://github.com/tomchristie/django-rest-framework/blob/e39d8410de26003421f7e644f9206833a3b9bbe0/rest_framework/serializers.py#L374 and field.run_validators https://github.com/tomchristie/django-rest-framework/blob/e39d8410de26003421f7e644f9206833a3b9bbe0/rest_framework/serializers.py#L397)
-
serializer.validate_[field] https://github.com/tomchristie/django-rest-framework/blob/e39d8410de26003421f7e644f9206833a3b9bbe0/rest_framework/serializers.py#L399为每个字段调用
- 序列化器级别的验证器称为(serializer.run_validation https://github.com/tomchristie/django-rest-framework/blob/e39d8410de26003421f7e644f9206833a3b9bbe0/rest_framework/serializers.py#L186其次是serializer.run_validators https://github.com/tomchristie/django-rest-framework/blob/e39d8410de26003421f7e644f9206833a3b9bbe0/rest_framework/serializers.py#L366)
-
serializer.validate https://github.com/tomchristie/django-rest-framework/blob/e39d8410de26003421f7e644f9206833a3b9bbe0/rest_framework/serializers.py#L367叫做
因此,您看到的问题是在序列化器级验证之前调用字段级验证。虽然我不推荐它,但您可以通过设置来删除字段级验证器extra_kwargs
在你的序列化器的元中。
class Meta:
extra_kwargs = {
"username": {
"validators": [],
},
}
您将需要重新实施unique
不过,请检查您自己的验证以及自动生成的任何其他验证器。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)