我有一个模型,其中“电子邮件”字段是唯一的。我认为这会使每封电子邮件都变为小写字母,因为它在User实例上具有normalize_email()方法。但是,它仅规范化域部分,因此,如果company@gmail.com存在,则Company@gmail.com被认为是唯一的。因此,我决定在序列化程序中创建validate_email()以始终返回小写电子邮件。这是一个字段验证,并在文档中进行了描述。
def validate_email(self, value):
return value.lower()
但是,看起来此方法在序列化程序检查数据库中是否存在值之后返回该值。这是一个示例:
如果我尝试使用user@gmail.com创建一个用户,并且该用户已经存在,则它将返回“用户已经存在”。但是,如果我使用User@gmail.com运行,它将首先运行SQL请求并检查User@gmail.com!= user@gmail.com,之后,它将尝试使用user@gmail.com创建新实例。因为它是从validate_email()返回的,而IntegrityError将被引发,因为它变成了已经在数据库中的user@gmail.com!
我可以做类似的事情
def validate_email(self, value):
norm_email = value.lower()
if User.objects.filter(email=norm_email).exists():
raise serializers.ValidationError("Not unique email")
return norm_email
但这是对数据库的另一个请求,我不想要它。
所以我的问题是,哪种方法运行SQL请求以检查DB中的唯一性?这样我就可以覆盖它并传递已经小写的值?
答案 0 :(得分:1)
transparent
更新
在内部进行DRF查询以检查唯一约束,因为在模型字段中,我们设置了 User.objects.filter(email__iexact=norm_email).exists()
。为了避免这种情况,我们需要在序列化程序中明确定义unique=True
字段 ,该字段 绕过 唯一检查验证
email
Django shell输出
class UserSerializer(serializers.ModelSerializer):
email = serializers.EmailField()
def validate_email(self, value):
lower_email = value.lower()
if User.objects.filter(email__iexact=lower_email).exists():
raise serializers.ValidationError("Duplicate")
return lower_email
class Meta:
model = User
fields = ('email',)