Michał Tabor
Michał Tabor

Reputation: 2467

Django - strange dictionary behaviour

I'm trying to override default error messages in my Django form:

class RegistrationForm(forms.Form):

    my_errors = {
        'required': 'To pole jest wymagane'
    }
    email = forms.EmailField(max_length=254, error_messages=my_errors.update({'invalid': 'Podaj prawidłowy adres e-mail'}))
    password = forms.CharField(error_messages=my_errors)
    firstname = forms.CharField(max_length=80, error_messages=my_errors)
    lastname = forms.CharField(max_length=80, error_messages=my_errors)

    def clean_email(self):
        email = self.cleaned_data['email']
        User = get_user_model
        try:
            User.objects.get(email=email)
            raise forms.ValidationError('Adres e-mail jest już zajęty')
        except User.DoesNotExist:
            return email

I can easily change 'required' error message cause it's the same for each field.

But for email field I'd like 'invalid' message to be more specific so I merge the existing dict with a one containing e-mail error message.

But it doesn't work: email field returns to default error messages while the rest of fields uses my error messages.

Please explain why it happens and how to fix it, thanks

Upvotes: 1

Views: 52

Answers (1)

shx2
shx2

Reputation: 64318

dict.update modifies the dict in-place, and returns None. Therefor, you are passing error_messages=None when declaring the email field.

Another undesirable side-effect of your code is that "invalid" is added to my_errors, and that extended my_errors is passed when declaring the rest of the fields.

You need to merge the dicts instead of using update, like:

class RegistrationForm(forms.Form):

    my_errors = {
        'required': 'To pole jest wymagane'
    }
    email = forms.EmailField(max_length=254, error_messages=dict(my_errors, invalid='Podaj prawidłowy adres e-mail'))
    password = forms.CharField(error_messages=my_errors)
    ...

Upvotes: 1

Related Questions