0

I am trying to raise ValidationError through validators.py or def clean(self) on an email field in the Django model to know if an email exists in the DB.

Below is a brief of my model:

class Profile(models.Model)
   ...
   email = models.EmailField()
   ...

   def __str__(self)
       return self.f_name

I know I can add unique=True to the model field to ensure that, or simply do a cleaned_data in forms, but the solution I want is that of validator.py or def clean(self) in models.py.

phagyrhe
  • 167
  • 1
  • 14
  • So what's the exact issue? You already know you can use a validator or override the model's `clean()` method to do what you want. What did you try? – dirkgroten Feb 07 '20 at 09:16
  • @dirkgroten I tried using `clean()` and `validators.py`, but unlike the straightforward way of checking if an email exists in forms, I couldn't get my head around writing the proper code to check if an email exists within `validators.py` or `clean()`. So, I wouldn't mind if I can be pointed to how I can write the code for that. – phagyrhe Feb 07 '20 at 09:40
  • `if Profile.objects.filter(email=self.email).exclude(pk=self.pk).exists()` would be the check in `clean()`. Look at the [docs](https://docs.djangoproject.com/en/3.0/ref/models/instances/#django.db.models.Model.clean) – dirkgroten Feb 07 '20 at 09:42

2 Answers2

0

For future reference, if anyone comes across the same issue, all thanks to @dirkgroten, I was able to resolve the problem with clean() in my models.py:

def clean(self)
     if Profile.objects.filter(email=self.email).exclude(pk=self.pk).exists():
            raise ValidationError({'email': _('Email already exists.')})
phagyrhe
  • 167
  • 1
  • 14
0

In your forms.py add this function to validate user email exist:

def clean_email(self):
    email = self.cleaned_data.get("email")
    if email and self._meta.model.objects.filter(email__iexact=email).exists():
        self._update_errors(
            ValidationError(
                {
                    "email": self.instance.unique_error_message(
                        self._meta.model, ["email"]
                    )
                }
            )
        )
    else:
        return email

Full custom class form look like this:

class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ["username", "email", "password1", "password2"]

    def clean_email(self):
        email = self.cleaned_data.get("email")
        if email and self._meta.model.objects.filter(email__iexact=email).exists():
            self._update_errors(
                ValidationError(
                    {
                        "email": self.instance.unique_error_message(
                            self._meta.model, ["email"]
                        )
                    }
                )
            )
        else:
            return email