A
A
Antonov Dmitry2016-05-02 15:00:32
Django
Antonov Dmitry, 2016-05-02 15:00:32

Django Unique email?

Hello. I have the following forms.py:

class RegisterForm(ModelForm):
    error_messages = {
        'password_mismatch': "Пароли не совпадают",
        'invalid': "Пользователь с таким e-mail уже существует",
    }
    password1 = forms.CharField(
        label="Пароль",
        strip=False,
        widget=forms.PasswordInput,
        )
    password2 = forms.CharField(
        label="Повторите пароль",
        strip=False,
        widget=forms.PasswordInput,
        help_text="Введите одинаковые пароли"
        )

    class Meta:
        model = User
        fields = ("username", "email",)

    def unique_email(self):
        email = self.cleaned_data["email"]
        if User.objects.filter(email=email).count() > 0 and email:
            raise forms.ValidationError(
                self.error_messages['invalid'],
                code='invalid',
                )
        return email

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(
                self.error_messages['password_mismatch'],
                code='password_mismatch',
            )
        self.instance.username = self.cleaned_data.get('username')
        password_validation.validate_password(self.cleaned_data.get('password2'), self.instance)
        return password2

    def save(self, commit=True):
        user = super(RegisterForm, self).save(commit=False)
        user.email = self.cleaned_data["email"]
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

And also views.py to it:
class RegisterView(FormView):
    template_name = 'blog/reg.html'
    form_class = RegisterForm
    success_url = '/login'

    def form_valid(self, form):
        form.unique_email()
        form.clean_password2()
        form.save()
        return super(RegisterView, self).form_valid(form)

Everything works fine, but I thought about the uniqueness of the email address, wrote a method, it also works, the problem is with forms.ValidationError - when you enter a non-unique email, it gives:
ValidationError at /reg/
['User with this e-mail already exists']
Request Method: POST
Request URL: 127.0.0.1:8000/reg
Django Version: 1.9.5
Exception Type: ValidationError
Exception Value:
['User with this e -mail already exists']

Which is also logical, but I want him to return me to the registration page and already there he wrote to me that my email is not unique. Tell me which way to dig?
ps I took many fragments from the django sources, and to be precise UserCreationForm, everything works fine with their method for checking the second password and returns to the registration page with an error.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
Roman Kitaev, 2016-05-02
@BlackTrub

1. It is better to set uniqueness at the database level. Redefine the user, add 2 in the Meta class unique_together =
. If the first item is discarded for some reason, replace the unique_email method with clean_email and the FormView will call it itself. In addition, you can’t catch exceptions from unique_email in any way, so he throws out an error.
3. if User.objects.filter(email=email).count() > 0 and email: - this is inefficient. First of all, you need to check that the email is not empty, and then that it is present in the database (fewer queries). In addition, count is expensive to call for this. It's better to do this:

if email and User.objects.filter(email=email).exists():

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question