diff --git a/django/forms/fields.py b/django/forms/fields.py
index 113a5aa..ea9e6dc 100644
|
a
|
b
|
class Field(object):
|
| 54 | 54 | |
| 55 | 55 | def __init__(self, required=True, widget=None, label=None, initial=None, |
| 56 | 56 | help_text=None, error_messages=None, show_hidden_initial=False, |
| 57 | | validators=[], localize=False): |
| | 57 | validators=[], localize=False, normalize=None): |
| 58 | 58 | # required -- Boolean that specifies whether the field is required. |
| 59 | 59 | # True by default. |
| 60 | 60 | # widget -- A Widget class, or instance of a Widget class, that should |
| … |
… |
class Field(object):
|
| 82 | 82 | self.help_text = u'' |
| 83 | 83 | else: |
| 84 | 84 | self.help_text = smart_unicode(help_text) |
| | 85 | self.normalize = normalize |
| 85 | 86 | widget = widget or self.widget |
| 86 | 87 | if isinstance(widget, type): |
| 87 | 88 | widget = widget() |
| … |
… |
class Field(object):
|
| 149 | 150 | Raises ValidationError for any errors. |
| 150 | 151 | """ |
| 151 | 152 | value = self.to_python(value) |
| | 153 | if self.normalize: |
| | 154 | value = self.normalize(value) |
| 152 | 155 | self.validate(value) |
| 153 | 156 | self.run_validators(value) |
| 154 | 157 | return value |
| … |
… |
class CharField(Field):
|
| 186 | 189 | self.validators.append(validators.MinLengthValidator(min_length)) |
| 187 | 190 | if max_length is not None: |
| 188 | 191 | self.validators.append(validators.MaxLengthValidator(max_length)) |
| | 192 | if self.normalize is None: |
| | 193 | self.normalize = lambda value: value.strip() |
| 189 | 194 | |
| 190 | 195 | def to_python(self, value): |
| 191 | 196 | "Returns a Unicode object." |
| … |
… |
class DateTimeField(BaseTemporalField):
|
| 427 | 432 | return datetime.datetime.strptime(value, format) |
| 428 | 433 | |
| 429 | 434 | class RegexField(CharField): |
| 430 | | def __init__(self, regex, max_length=None, min_length=None, error_message=None, *args, **kwargs): |
| | 435 | def __init__(self, regex, max_length=None, min_length=None, error_message=None, normalize=False, *args, **kwargs): |
| 431 | 436 | """ |
| 432 | 437 | regex can be either a string or a compiled regular expression object. |
| 433 | 438 | error_message is an optional error message to use, if |
| … |
… |
class RegexField(CharField):
|
| 438 | 443 | error_messages = kwargs.get('error_messages') or {} |
| 439 | 444 | error_messages['invalid'] = error_message |
| 440 | 445 | kwargs['error_messages'] = error_messages |
| 441 | | super(RegexField, self).__init__(max_length, min_length, *args, **kwargs) |
| | 446 | super(RegexField, self).__init__(max_length, min_length, normalize=normalize, *args, **kwargs) |
| 442 | 447 | if isinstance(regex, basestring): |
| 443 | 448 | regex = re.compile(regex) |
| 444 | 449 | self.regex = regex |
| … |
… |
class EmailField(CharField):
|
| 450 | 455 | } |
| 451 | 456 | default_validators = [validators.validate_email] |
| 452 | 457 | |
| 453 | | def clean(self, value): |
| 454 | | value = self.to_python(value).strip() |
| 455 | | return super(EmailField, self).clean(value) |
| 456 | | |
| 457 | 458 | class FileField(Field): |
| 458 | 459 | widget = ClearableFileInput |
| 459 | 460 | default_error_messages = { |
diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt
index 66c05e5..c4df0ba 100644
|
a
|
b
|
as the rendered output.
|
| 278 | 278 | See the :ref:`format localization <format-localization>` documentation for |
| 279 | 279 | more information. |
| 280 | 280 | |
| | 281 | ``normalize`` |
| | 282 | ~~~~~~~~~~~~ |
| | 283 | |
| | 284 | .. versionadded:: New in Django development version |
| | 285 | |
| | 286 | .. attribute:: Field.normalize |
| | 287 | |
| | 288 | The ``normalize`` argument lets you normalize the input data before it is validated. |
| | 289 | A common use-case is stripping leading and trailinig whitespace from CharFields:: |
| | 290 | |
| | 291 | >>> foo = forms.CharField(normalize=lambda x: x.strip()) |
| | 292 | >>> foo.clean(' ') |
| | 293 | Traceback (most recent call last): |
| | 294 | ... |
| | 295 | ValidationError: [u'This field is required.'] |
| | 296 | |
| | 297 | This behavior for CharField enabled by default. Set `normalize=False`` to disable it. |
| | 298 | |
| | 299 | >>> foo = forms.CharField(normalize=False) |
| | 300 | >>> foo.clean(' ') |
| | 301 | u' ' |
| | 302 | |
| | 303 | |
| 281 | 304 | .. _built-in fields: |
| 282 | 305 | |
| 283 | 306 | Built-in ``Field`` classes |
| … |
… |
For each field, we describe the default widget used if you don't specify
|
| 317 | 340 | |
| 318 | 341 | * Default widget: ``TextInput`` |
| 319 | 342 | * Empty value: ``''`` (an empty string) |
| 320 | | * Normalizes to: A Unicode object. |
| | 343 | * Normalizes to: A Unicode object with stripped leading and trailinig whitespace. |
| | 344 | Set ``normalize=False`` to disable stripping spaces or set |
| | 345 | ``normilize=your_callable_name`` to change normalization behavior. |
| 321 | 346 | * Validates ``max_length`` or ``min_length``, if they are provided. |
| 322 | 347 | Otherwise, all inputs are valid. |
| 323 | 348 | * Error message keys: ``required``, ``max_length``, ``min_length`` |
| … |
… |
Takes four optional arguments:
|
| 481 | 506 | |
| 482 | 507 | * Default widget: ``TextInput`` |
| 483 | 508 | * Empty value: ``''`` (an empty string) |
| 484 | | * Normalizes to: A Unicode object. |
| 485 | | * Validates that the given value is a valid email address, using a |
| | 509 | * Normalizes to: A Unicode object with stripped leading and trailinig whitespace. |
| | 510 | Set ``normalize=False`` to disable stripping spaces or set |
| | 511 | ``normilize=your_callable_name`` to change normalization behavior. |
| | 512 | * Validates that the given value is a valid e-mail address, using a |
| 486 | 513 | moderately complex regular expression. |
| 487 | 514 | * Error message keys: ``required``, ``invalid`` |
| 488 | 515 | |
| … |
… |
Takes two optional arguments for validation:
|
| 618 | 645 | |
| 619 | 646 | * Default widget: ``TextInput`` |
| 620 | 647 | * Empty value: ``''`` (an empty string) |
| 621 | | * Normalizes to: A Unicode object. |
| | 648 | * Normalizes to: A Unicode object with stripped leading and trailinig whitespace. |
| | 649 | Set ``normalize=False`` to disable stripping spaces or set |
| | 650 | ``normilize=your_callable_name`` to change normalization behavior. |
| 622 | 651 | * Validates that the given value is a valid IPv4 address, using a regular |
| 623 | 652 | expression. |
| 624 | 653 | * Error message keys: ``required``, ``invalid`` |
| … |
… |
and the error message as the value.
|
| 746 | 775 | |
| 747 | 776 | * Default widget: ``TextInput`` |
| 748 | 777 | * Empty value: ``''`` (an empty string) |
| 749 | | * Normalizes to: A Unicode object. |
| | 778 | * Normalizes to: A Unicode object with stripped leading and trailinig whitespace. |
| | 779 | Set ``normalize=False`` to disable stripping spaces or set |
| | 780 | ``normilize=your_callable_name`` to change normalization behavior. |
| 750 | 781 | * Validates that the given value contains only letters, numbers, |
| 751 | 782 | underscores, and hyphens. |
| 752 | 783 | * Error messages: ``required``, ``invalid`` |
| … |
… |
If no ``input_formats`` argument is provided, the default input formats are::
|
| 785 | 816 | |
| 786 | 817 | * Default widget: ``TextInput`` |
| 787 | 818 | * Empty value: ``''`` (an empty string) |
| 788 | | * Normalizes to: A Unicode object. |
| | 819 | * Normalizes to: A Unicode object with stripped leading and trailinig whitespace. |
| | 820 | Set ``normalize=False`` to disable stripping spaces or set |
| | 821 | ``normilize=your_callable_name`` to change normalization behavior. |
| 789 | 822 | * Validates that the given value is a valid URL. |
| 790 | 823 | * Error message keys: ``required``, ``invalid``, ``invalid_link`` |
| 791 | 824 | |
diff --git a/tests/regressiontests/forms/tests/fields.py b/tests/regressiontests/forms/tests/fields.py
index 6780413..1dcff0d 100644
|
a
|
b
|
class FieldsTests(TestCase):
|
| 131 | 131 | self.assertEqual(f.max_length, None) |
| 132 | 132 | self.assertEqual(f.min_length, 10) |
| 133 | 133 | |
| | 134 | def test_charfield_normalize(self): |
| | 135 | f = CharField() |
| | 136 | self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, " \t") |
| | 137 | |
| | 138 | def test_charfield_normalize_false(self): |
| | 139 | f = CharField(normalize=False) |
| | 140 | self.assertEqual(" \t", f.clean(" \t")) |
| | 141 | |
| 134 | 142 | # IntegerField ################################################################ |
| 135 | 143 | |
| 136 | 144 | def test_integerfield_1(self): |