Fixed #17051 -- Removed some 'invalid' field error messages

When the 'invalid' error message is set at field level, it masks
the error message raised by the validator, if any.
This commit is contained in:
Claude Paroz 2013-03-14 16:19:59 +01:00
parent 34d098665d
commit 2f121dfe63
7 changed files with 59 additions and 57 deletions

View File

@ -7,7 +7,7 @@ from django.contrib.auth.forms import (UserCreationForm, AuthenticationForm,
ReadOnlyPasswordHashField, ReadOnlyPasswordHashWidget)
from django.contrib.auth.tests.utils import skipIfCustomUser
from django.core import mail
from django.forms.fields import Field, EmailField, CharField
from django.forms.fields import Field, CharField
from django.test import TestCase
from django.test.utils import override_settings
from django.utils.encoding import force_text
@ -322,8 +322,7 @@ class PasswordResetFormTest(TestCase):
data = {'email': 'not valid'}
form = PasswordResetForm(data)
self.assertFalse(form.is_valid())
self.assertEqual(form['email'].errors,
[force_text(EmailField.default_error_messages['invalid'])])
self.assertEqual(form['email'].errors, [_('Enter a valid email address.')])
def test_nonexistant_email(self):
# Test nonexistant email address. This should not fail because it would

View File

@ -80,7 +80,7 @@ def validate_integer(value):
class EmailValidator(object):
message = _('Enter a valid e-mail address.')
message = _('Enter a valid email address.')
code = 'invalid'
user_regex = re.compile(
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*$" # dot-atom

View File

@ -49,9 +49,10 @@ class Field(object):
widget = TextInput # Default widget to use when rendering this type of Field.
hidden_widget = HiddenInput # Default widget to use when rendering this as "hidden".
default_validators = [] # Default set of validators
# Add an 'invalid' entry to default_error_message if you want a specific
# field error message not raised by the field validators.
default_error_messages = {
'required': _('This field is required.'),
'invalid': _('Enter a valid value.'),
}
empty_values = list(validators.EMPTY_VALUES)
@ -225,8 +226,6 @@ class CharField(Field):
class IntegerField(Field):
default_error_messages = {
'invalid': _('Enter a whole number.'),
'max_value': _('Ensure this value is less than or equal to %(limit_value)s.'),
'min_value': _('Ensure this value is greater than or equal to %(limit_value)s.'),
}
def __init__(self, max_value=None, min_value=None, *args, **kwargs):
@ -504,9 +503,6 @@ class RegexField(CharField):
class EmailField(CharField):
widget = EmailInput
default_error_messages = {
'invalid': _('Enter a valid email address.'),
}
default_validators = [validators.validate_email]
def clean(self, value):
@ -1082,9 +1078,6 @@ class SplitDateTimeField(MultiValueField):
class IPAddressField(CharField):
default_error_messages = {
'invalid': _('Enter a valid IPv4 address.'),
}
default_validators = [validators.validate_ipv4_address]
def to_python(self, value):
@ -1094,13 +1087,9 @@ class IPAddressField(CharField):
class GenericIPAddressField(CharField):
default_error_messages = {}
def __init__(self, protocol='both', unpack_ipv4=False, *args, **kwargs):
self.unpack_ipv4 = unpack_ipv4
self.default_validators, invalid_error_message = \
validators.ip_address_validators(protocol, unpack_ipv4)
self.default_error_messages['invalid'] = invalid_error_message
self.default_validators = validators.ip_address_validators(protocol, unpack_ipv4)[0]
super(GenericIPAddressField, self).__init__(*args, **kwargs)
def to_python(self, value):
@ -1108,14 +1097,9 @@ class GenericIPAddressField(CharField):
return ''
value = value.strip()
if value and ':' in value:
return clean_ipv6_address(value,
self.unpack_ipv4, self.error_messages['invalid'])
return clean_ipv6_address(value, self.unpack_ipv4)
return value
class SlugField(CharField):
default_error_messages = {
'invalid': _("Enter a valid 'slug' consisting of letters, numbers,"
" underscores or hyphens."),
}
default_validators = [validators.validate_slug]

View File

@ -5,7 +5,7 @@ from django.core.exceptions import ValidationError
from django.utils.six.moves import xrange
def clean_ipv6_address(ip_str, unpack_ipv4=False,
error_message="This is not a valid IPv6 address"):
error_message="This is not a valid IPv6 address."):
"""
Cleans a IPv6 address string.

View File

@ -181,24 +181,20 @@ the field's ``validators`` argument, or defined on the Field class itself with
the ``default_validators`` attribute.
Simple validators can be used to validate values inside the field, let's have
a look at Django's ``EmailField``::
a look at Django's ``SlugField``::
class EmailField(CharField):
default_error_messages = {
'invalid': _('Enter a valid email address.'),
}
default_validators = [validators.validate_email]
class SlugField(CharField):
default_validators = [validators.validate_slug]
As you can see, ``EmailField`` is just a ``CharField`` with customized error
message and a validator that validates email addresses. This can also be done
on field definition so::
As you can see, ``SlugField`` is just a ``CharField`` with a customized
validator that validates that submitted text obeys to some character rules.
This can also be done on field definition so::
email = forms.EmailField()
slug = forms.SlugField()
is equivalent to::
email = forms.CharField(validators=[validators.validate_email],
error_messages={'invalid': _('Enter a valid email address.')})
slug = forms.CharField(validators=[validators.validate_slug])
Form field default cleaning

View File

@ -506,11 +506,11 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '256.125.1.5')
self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '12345:2:3:4')
self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1::2:3::4')
self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a')
self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8')
self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1:2')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '12345:2:3:4')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1::2:3::4')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1:2')
def test_generic_ipaddress_as_ipv4_only(self):
f = GenericIPAddressField(protocol="IPv4")
@ -535,11 +535,11 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '256.125.1.5')
self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '12345:2:3:4')
self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '1::2:3::4')
self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a')
self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8')
self.assertFormErrors(['Enter a valid IPv6 address.'], f.clean, '1:2')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '12345:2:3:4')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1::2:3::4')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1:2')
def test_generic_ipaddress_as_generic_not_required(self):
f = GenericIPAddressField(required=False)
@ -552,11 +552,11 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '256.125.1.5')
self.assertEqual(f.clean(' fe80::223:6cff:fe8a:2e8a '), 'fe80::223:6cff:fe8a:2e8a')
self.assertEqual(f.clean(' 2a02::223:6cff:fe8a:2e8a '), '2a02::223:6cff:fe8a:2e8a')
self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '12345:2:3:4')
self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1::2:3::4')
self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a')
self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8')
self.assertFormErrors(['Enter a valid IPv4 or IPv6 address.'], f.clean, '1:2')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '12345:2:3:4')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1::2:3::4')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, 'foo::223:6cff:fe8a:2e8a')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1::2:3:4:5:6:7:8')
self.assertFormErrors(['This is not a valid IPv6 address.'], f.clean, '1:2')
def test_generic_ipaddress_normalization(self):
# Test the normalising code

View File

@ -1,16 +1,39 @@
from __future__ import unicode_literals
from django import forms
from django.core import validators
from django.core.exceptions import ValidationError
from django.utils.unittest import TestCase
class UserForm(forms.Form):
full_name = forms.CharField(
max_length = 50,
validators = [
validators.validate_integer,
validators.validate_email,
]
)
string = forms.CharField(
max_length = 50,
validators = [
validators.RegexValidator(
regex='^[a-zA-Z]*$',
message="Letters only.",
)
]
)
class TestFieldWithValidators(TestCase):
def test_all_errors_get_reported(self):
field = forms.CharField(
validators=[validators.validate_integer, validators.validate_email]
)
self.assertRaises(ValidationError, field.clean, 'not int nor mail')
form = UserForm({'full_name': 'not int nor mail', 'string': '2 is not correct'})
self.assertRaises(ValidationError, form.fields['full_name'].clean, 'not int nor mail')
try:
field.clean('not int nor mail')
form.fields['full_name'].clean('not int nor mail')
except ValidationError as e:
self.assertEqual(2, len(e.messages))
self.assertFalse(form.is_valid())
self.assertEqual(form.errors['string'], ["Letters only."])