I have a model where Email field is unique. I thought it would make every email lowercase as it has normalize_email() method on User instance. However, it normalizes domain part only so Company@gmail.com is considered to be unique if company@gmail.com exists. So I decided to create validate_email() in my serializer to always return a lowercase email. It is a field validation and it is described in docs.
def validate_email(self, value):
return value.lower()
However, looks like this method returns the value after the serializer has checked if the value exists in the database. Here is an example:
if I try to create a user with user@gmail.com and it already exists, it will return "user already exists" which is expected. However, if I run with User@gmail.com it will run a SQL request first and check User@gmail.com != user@gmail.com and after that it'll try to create a new instance with user@gmail.com because it is returned from validate_email() and IntegrityError will be raised because it becomes user@gmail.com which is already in DB!
I could do something like
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
but this is another request to DB and I don't want it.
So my question is what method runs a SQL request to check uniqueness in DB? So that I can override it and pass value already lowercased?