1

I have the following form in django:

class UserEmailRegistrationForm(forms.Form):
    password = forms.PasswordField(max_length=32, label=_('Password'),
                                   validators=[validators.validate_password])
    email = forms.EmailField(label=_('Email'), 
                             validators=[validators.validate_email])
    first_name = forms.CharField(max_length=35, label=_('First name'), 
                                 validators=[validators.validate_name])
    last_name = forms.CharField(max_length=35, label=_('Last name'), 
                                validators=[validators.validate_name])

Most validators are custom, but validate_email is as seen in django.core.validators. Also, here's the relevant part of my view:

form = UserEmailRegistrationForm(PUT)       
    # Validate incoming data
    if not form.is_valid():
        return HttpResponse(form.errors.as_json(), 
                            content_type='application/json', status=422)

All validators are working fine, but I get Enter a valid email address. twice in form.errors when I pass along an invalid email address. Here's the response I get:

{"email": [{"message": "Enter a valid email address.", "code": "invalid"}, {"message": "Enter a valid email address.", "code": "invalid"}]}

What could be causing this and how can I resolve it?

2 Answers 2

3

To debug / see what's happening. In your IDE click on EmailField and follow the hierarchy...

1.Your code:

email = forms.EmailField(label=_('Email'), 
                         validators=[validators.validate_email])

2.EmailField:

class EmailField(CharField):
    widget = EmailInput
    default_validators = [validators.validate_email]

3.CharField / nothing interesting.

class CharField(Field): ...

4.Field.__init__(...):

...
self.validators = self.default_validators + validators
super(Field, self).__init__()

In short, you're using validate_email twice.

Sign up to request clarification or add additional context in comments.

1 Comment

Fixed it! It's a strange behaviour, though. Maybe the parameter should be called something like "extra_validators", it seams more reasonable.
1

As François intimated, there a two identical validators associated with your email field. The first is there by default, and then you add a second one by supplying a value for the validators keyword argument (validators=[validators.validate_email]). This validator list is appended to any default ones. Hence you are seeing 2 validation error messages.

$ python manage.py shell
>>> from django import forms
>>> from django.core import validators
>>> email = forms.EmailField(label=_('Email'), validators=[validators.validate_email])
>>> email.validators
[<django.core.validators.EmailValidator object at 0x2bc0190>, <django.core.validators.EmailValidator object at 0x2bc0190>]

So you can see above that there are 2 registered validators. When the form is validated both are executed:

>>> email.run_validators('[email protected]')
>>> email.run_validators('abc')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/mhawke/virtualenvs/django_1.6/lib/python2.7/site-packages/django/forms/fields.py", line 139, in run_validators
    raise ValidationError(errors)
ValidationError: [u'Enter a valid email address.', u'Enter a valid email address.']

To fix, simply declare the email field without the validator:

>>> email = forms.EmailField(label=_('Email'))
>>> email.validators
[<django.core.validators.EmailValidator object at 0x2bc0190>]
>>> email.run_validators('[email protected]')
>>> email.run_validators('abc')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/mhawke/virtualenvs/django_1.6/lib/python2.7/site-packages/django/forms/fields.py", line 139, in run_validators
    raise ValidationError(errors)
ValidationError: [u'Enter a valid email address.']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.