From c012b8964e596423b68f4ec4b1b57253cf0ae7b0 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Sun, 16 Sep 2007 11:38:32 +0000 Subject: [PATCH] Fixed #4067 -- Fixed validation of IPAddressFields in newforms. Thanks to neils and the team in the Copenhagen sprint group. git-svn-id: http://code.djangoproject.com/svn/django/trunk@6357 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/models/fields/__init__.py | 5 +++ django/newforms/fields.py | 10 ++++- docs/newforms.txt | 11 +++++- tests/regressiontests/forms/tests.py | 55 ++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 7a4c15c3c14ad..6df1e342886b6 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -880,6 +880,11 @@ def get_manipulator_field_objs(self): def validate(self, field_data, all_data): validators.isValidIPAddress4(field_data, None) + def formfield(self, **kwargs): + defaults = {'form_class': forms.IPAddressField} + defaults.update(kwargs) + return super(IPAddressField, self).formfield(**defaults) + class NullBooleanField(Field): empty_strings_allowed = False def __init__(self, *args, **kwargs): diff --git a/django/newforms/fields.py b/django/newforms/fields.py index 8fb1d4f392a41..a39987e1b582d 100644 --- a/django/newforms/fields.py +++ b/django/newforms/fields.py @@ -26,7 +26,7 @@ 'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField', 'BooleanField', 'ChoiceField', 'NullBooleanField', 'MultipleChoiceField', 'ComboField', 'MultiValueField', 'FloatField', 'DecimalField', - 'SplitDateTimeField', + 'SplitDateTimeField', 'IPAddressField', ) # These values, if given to to_python(), will trigger the self.required check. @@ -635,3 +635,11 @@ def compress(self, data_list): raise ValidationError(ugettext(u'Enter a valid time.')) return datetime.datetime.combine(*data_list) return None + +ipv4_re = re.compile(r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$') + +class IPAddressField(RegexField): + def __init__(self, *args, **kwargs): + RegexField.__init__(self, ipv4_re, + error_message=ugettext(u'Enter a valid IPv4 address.'), + *args, **kwargs) diff --git a/docs/newforms.txt b/docs/newforms.txt index 691aee7e4440c..2c8f67ce32b3b 100644 --- a/docs/newforms.txt +++ b/docs/newforms.txt @@ -1284,6 +1284,15 @@ When you use a ``FileField`` on a form, you must also remember to Takes two optional arguments for validation, ``max_value`` and ``min_value``. These control the range of values permitted in the field. +``IPAddressField`` +~~~~~~~~~~~~~~~~~~ + + * Default widget: ``TextInput`` + * Empty value: ``''`` (an empty string) + * Normalizes to: A Unicode object. + * Validates that the given value is a valid IPv4 address, using a regular + expression. + ``MultipleChoiceField`` ~~~~~~~~~~~~~~~~~~~~~~~ @@ -1710,7 +1719,7 @@ the full list of conversions: ``ForeignKey`` ``ModelChoiceField`` (see below) ``ImageField`` ``ImageField`` ``IntegerField`` ``IntegerField`` - ``IPAddressField`` ``CharField`` + ``IPAddressField`` ``IPAddressField`` ``ManyToManyField`` ``ModelMultipleChoiceField`` (see below) ``NullBooleanField`` ``CharField`` diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index a3e61c8f06467..616d6e5ff56f6 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -3834,6 +3834,61 @@ >>> f.cleaned_data {'field1': u'some text,JP,2007-04-25 06:24:00'} + +# IPAddressField ################################################################## + +>>> f = IPAddressField() +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean(None) +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean('127.0.0.1') +u'127.0.0.1' +>>> f.clean('foo') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid IPv4 address.'] +>>> f.clean('127.0.0.') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid IPv4 address.'] +>>> f.clean('1.2.3.4.5') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid IPv4 address.'] +>>> f.clean('256.125.1.5') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid IPv4 address.'] + +>>> f = IPAddressField(required=False) +>>> f.clean('') +u'' +>>> f.clean(None) +u'' +>>> f.clean('127.0.0.1') +u'127.0.0.1' +>>> f.clean('foo') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid IPv4 address.'] +>>> f.clean('127.0.0.') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid IPv4 address.'] +>>> f.clean('1.2.3.4.5') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid IPv4 address.'] +>>> f.clean('256.125.1.5') +Traceback (most recent call last): +... +ValidationError: [u'Enter a valid IPv4 address.'] + ################################# # Tests of underlying functions # #################################