Ticket #19997: formfields_empty_values.diff

File formfields_empty_values.diff, 13.6 KB (added by loic84, 2 years ago)
  • django/forms/fields.py

    diff --git a/django/forms/fields.py b/django/forms/fields.py
    index c7ed085..bc37701 100644
    a b class Field(object): 
    5353        'required': _('This field is required.'),
    5454        'invalid': _('Enter a valid value.'),
    5555    }
     56    empty_values = list(validators.EMPTY_VALUES)
    5657
    5758    # Tracks each time a Field instance is created. Used to retain order.
    5859    creation_counter = 0
    class Field(object): 
    125126        return value
    126127
    127128    def validate(self, value):
    128         if value in validators.EMPTY_VALUES and self.required:
     129        if value in self.empty_values and self.required:
    129130            raise ValidationError(self.error_messages['required'])
    130131
    131132    def run_validators(self, value):
    132         if value in validators.EMPTY_VALUES:
     133        if value in self.empty_values:
    133134            return
    134135        errors = []
    135136        for v in self.validators:
    class CharField(Field): 
    210211
    211212    def to_python(self, value):
    212213        "Returns a Unicode object."
    213         if value in validators.EMPTY_VALUES:
     214        if value in self.empty_values:
    214215            return ''
    215216        return smart_text(value)
    216217
    class IntegerField(Field): 
    244245        of int(). Returns None for empty values.
    245246        """
    246247        value = super(IntegerField, self).to_python(value)
    247         if value in validators.EMPTY_VALUES:
     248        if value in self.empty_values:
    248249            return None
    249250        if self.localize:
    250251            value = formats.sanitize_separators(value)
    class FloatField(IntegerField): 
    275276        of float(). Returns None for empty values.
    276277        """
    277278        value = super(IntegerField, self).to_python(value)
    278         if value in validators.EMPTY_VALUES:
     279        if value in self.empty_values:
    279280            return None
    280281        if self.localize:
    281282            value = formats.sanitize_separators(value)
    class DecimalField(IntegerField): 
    311312        than max_digits in the number, and no more than decimal_places digits
    312313        after the decimal point.
    313314        """
    314         if value in validators.EMPTY_VALUES:
     315        if value in self.empty_values:
    315316            return None
    316317        if self.localize:
    317318            value = formats.sanitize_separators(value)
    class DecimalField(IntegerField): 
    324325
    325326    def validate(self, value):
    326327        super(DecimalField, self).validate(value)
    327         if value in validators.EMPTY_VALUES:
     328        if value in self.empty_values:
    328329            return
    329330        # Check for NaN, Inf and -Inf values. We can't compare directly for NaN,
    330331        # since it is never equal to itself. However, NaN is the only value that
    class DateField(BaseTemporalField): 
    401402        Validates that the input can be converted to a date. Returns a Python
    402403        datetime.date object.
    403404        """
    404         if value in validators.EMPTY_VALUES:
     405        if value in self.empty_values:
    405406            return None
    406407        if isinstance(value, datetime.datetime):
    407408            return value.date()
    class TimeField(BaseTemporalField): 
    425426        Validates that the input can be converted to a time. Returns a Python
    426427        datetime.time object.
    427428        """
    428         if value in validators.EMPTY_VALUES:
     429        if value in self.empty_values:
    429430            return None
    430431        if isinstance(value, datetime.time):
    431432            return value
    class DateTimeField(BaseTemporalField): 
    451452        Validates that the input can be converted to a datetime. Returns a
    452453        Python datetime.datetime object.
    453454        """
    454         if value in validators.EMPTY_VALUES:
     455        if value in self.empty_values:
    455456            return None
    456457        if isinstance(value, datetime.datetime):
    457458            return from_current_timezone(value)
    class DateTimeField(BaseTemporalField): 
    463464            # components: date and time.
    464465            if len(value) != 2:
    465466                raise ValidationError(self.error_messages['invalid'])
    466             if value[0] in validators.EMPTY_VALUES and value[1] in validators.EMPTY_VALUES:
     467            if value[0] in self.empty_values and value[1] in self.empty_values:
    467468                return None
    468469            value = '%s %s' % tuple(value)
    469470        result = super(DateTimeField, self).to_python(value)
    class FileField(Field): 
    531532        super(FileField, self).__init__(*args, **kwargs)
    532533
    533534    def to_python(self, data):
    534         if data in validators.EMPTY_VALUES:
     535        if data in self.empty_values:
    535536            return None
    536537
    537538        # UploadedFile objects should have name and size attributes.
    class FileField(Field): 
    562563                return False
    563564            # If the field is required, clearing is not possible (the widget
    564565            # shouldn't return False data in that case anyway). False is not
    565             # in validators.EMPTY_VALUES; if a False value makes it this far
     566            # in self.empty_value; if a False value makes it this far
    566567            # it should be validated from here on out as None (so it will be
    567568            # caught by the required check).
    568569            data = None
    class ChoiceField(Field): 
    763764
    764765    def to_python(self, value):
    765766        "Returns a Unicode object."
    766         if value in validators.EMPTY_VALUES:
     767        if value in self.empty_values:
    767768            return ''
    768769        return smart_text(value)
    769770
    class TypedChoiceField(ChoiceField): 
    801802        """
    802803        value = super(TypedChoiceField, self).to_python(value)
    803804        super(TypedChoiceField, self).validate(value)
    804         if value == self.empty_value or value in validators.EMPTY_VALUES:
     805        if value == self.empty_value or value in self.empty_values:
    805806            return self.empty_value
    806807        try:
    807808            value = self.coerce(value)
    class TypedMultipleChoiceField(MultipleChoiceField): 
    864865        """
    865866        value = super(TypedMultipleChoiceField, self).to_python(value)
    866867        super(TypedMultipleChoiceField, self).validate(value)
    867         if value == self.empty_value or value in validators.EMPTY_VALUES:
     868        if value == self.empty_value or value in self.empty_values:
    868869            return self.empty_value
    869870        new_value = []
    870871        for choice in value:
    class MultiValueField(Field): 
    945946        clean_data = []
    946947        errors = ErrorList()
    947948        if not value or isinstance(value, (list, tuple)):
    948             if not value or not [v for v in value if v not in validators.EMPTY_VALUES]:
     949            if not value or not [v for v in value if v not in self.empty_values]:
    949950                if self.required:
    950951                    raise ValidationError(self.error_messages['required'])
    951952                else:
    class MultiValueField(Field): 
    957958                field_value = value[i]
    958959            except IndexError:
    959960                field_value = None
    960             if self.required and field_value in validators.EMPTY_VALUES:
     961            if self.required and field_value in self.empty_values:
    961962                raise ValidationError(self.error_messages['required'])
    962963            try:
    963964                clean_data.append(field.clean(field_value))
    class SplitDateTimeField(MultiValueField): 
    10711072        if data_list:
    10721073            # Raise a validation error if time or date is empty
    10731074            # (possible if SplitDateTimeField has required=False).
    1074             if data_list[0] in validators.EMPTY_VALUES:
     1075            if data_list[0] in self.empty_values:
    10751076                raise ValidationError(self.error_messages['invalid_date'])
    1076             if data_list[1] in validators.EMPTY_VALUES:
     1077            if data_list[1] in self.empty_values:
    10771078                raise ValidationError(self.error_messages['invalid_time'])
    10781079            result = datetime.datetime.combine(*data_list)
    10791080            return from_current_timezone(result)
    class IPAddressField(CharField): 
    10871088    default_validators = [validators.validate_ipv4_address]
    10881089
    10891090    def to_python(self, value):
    1090         if value in EMPTY_VALUES:
     1091        if value in self.empty_values:
    10911092            return ''
    10921093        return value.strip()
    10931094
    class GenericIPAddressField(CharField): 
    11031104        super(GenericIPAddressField, self).__init__(*args, **kwargs)
    11041105
    11051106    def to_python(self, value):
    1106         if value in validators.EMPTY_VALUES:
     1107        if value in self.empty_values:
    11071108            return ''
    11081109        value = value.strip()
    11091110        if value and ':' in value:
  • django/forms/models.py

    diff --git a/django/forms/models.py b/django/forms/models.py
    index 87fd546..7609bb7 100644
    a b and database field objects. 
    66from __future__ import absolute_import, unicode_literals
    77
    88from django.core.exceptions import ValidationError, NON_FIELD_ERRORS, FieldError
    9 from django.core.validators import EMPTY_VALUES
    109from django.forms.fields import Field, ChoiceField
    1110from django.forms.forms import BaseForm, get_declared_fields
    1211from django.forms.formsets import BaseFormSet, formset_factory
    class BaseModelForm(BaseForm): 
    301300            else:
    302301                form_field = self.fields[field]
    303302                field_value = self.cleaned_data.get(field, None)
    304                 if not f.blank and not form_field.required and field_value in EMPTY_VALUES:
     303                if not f.blank and not form_field.required and field_value in form_field.empty_values:
    305304                    exclude.append(f.name)
    306305        return exclude
    307306
    class InlineForeignKeyField(Field): 
    880879        super(InlineForeignKeyField, self).__init__(*args, **kwargs)
    881880
    882881    def clean(self, value):
    883         if value in EMPTY_VALUES:
     882        if value in self.empty_values:
    884883            if self.pk_field:
    885884                return None
    886885            # if there is no value act as we did before.
    class ModelChoiceField(ChoiceField): 
    1000999        return super(ModelChoiceField, self).prepare_value(value)
    10011000
    10021001    def to_python(self, value):
    1003         if value in EMPTY_VALUES:
     1002        if value in self.empty_values:
    10041003            return None
    10051004        try:
    10061005            key = self.to_field_name or 'pk'
  • django/test/testcases.py

    diff --git a/django/test/testcases.py b/django/test/testcases.py
    index 345e4b1..44ddb62 100644
    a b from django.core.management.color import no_style 
    2727from django.core.servers.basehttp import (WSGIRequestHandler, WSGIServer,
    2828    WSGIServerException)
    2929from django.core.urlresolvers import clear_url_caches
    30 from django.core.validators import EMPTY_VALUES
    3130from django.db import connection, connections, DEFAULT_DB_ALIAS, transaction
    3231from django.forms.fields import CharField
    3332from django.http import QueryDict
    class SimpleTestCase(ut2.TestCase): 
    322321                    raised error messages.
    323322            field_args: the args passed to instantiate the field
    324323            field_kwargs: the kwargs passed to instantiate the field
    325             empty_value: the expected clean output for inputs in EMPTY_VALUES
     324            empty_value: the expected clean output for inputs in empty_values
    326325
    327326        """
    328327        if field_args is None:
    class SimpleTestCase(ut2.TestCase): 
    347346            self.assertEqual(context_manager.exception.messages, errors)
    348347        # test required inputs
    349348        error_required = [force_text(required.error_messages['required'])]
    350         for e in EMPTY_VALUES:
     349        for e in required.empty_values:
    351350            with self.assertRaises(ValidationError) as context_manager:
    352351                required.clean(e)
    353352            self.assertEqual(context_manager.exception.messages,
  • docs/topics/testing/overview.txt

    diff --git a/docs/topics/testing/overview.txt b/docs/topics/testing/overview.txt
    index 3b2babd..b917086 100644
    a b your test suite. 
    14801480        error messages.
    14811481    :param field_args: the args passed to instantiate the field.
    14821482    :param field_kwargs: the kwargs passed to instantiate the field.
    1483     :param empty_value: the expected clean output for inputs in ``EMPTY_VALUES``.
     1483    :param empty_value: the expected clean output for inputs in ``empty_values``.
    14841484
    14851485    For example, the following code tests that an ``EmailField`` accepts
    14861486    "a@a.com" as a valid email address, but rejects "aaa" with a reasonable
  • tests/forms_tests/tests/forms.py

    diff --git a/tests/forms_tests/tests/forms.py b/tests/forms_tests/tests/forms.py
    index f856e30..1f65045 100644
    a b class FormsTestCase(TestCase): 
    17971797        form = NameForm(data={'name' : ['fname', 'lname']})
    17981798        self.assertTrue(form.is_valid())
    17991799        self.assertEqual(form.cleaned_data, {'name' : 'fname lname'})
     1800
     1801    def test_empty_values(self):
     1802        class OldFakeJSONField(forms.Field):
     1803            def to_python(self, value):
     1804                if value in [None, '']:
     1805                    return None
     1806                # Fake json.loads.
     1807                if value == '{}':
     1808                    return {}
     1809                raise NotImplementedError
     1810
     1811            def prepare_value(self, value):
     1812                if value in [None, '']:
     1813                    return ''
     1814                # Fake json.dumps
     1815                if value == {}:
     1816                    return '{}'
     1817                raise NotImplementedError
     1818
     1819        class NewFakeJSONField(OldFakeJSONField):
     1820            empty_values = [None, '']
     1821
     1822        class FakeJSONForm(forms.Form):
     1823            old = OldFakeJSONField()
     1824            new = NewFakeJSONField()
     1825        form = FakeJSONForm(data={'old': '{}', 'new': '{}'});
     1826        form.full_clean()
     1827        self.assertEqual(form.errors, {'old': ['This field is required.']})
     1828        self.assertEqual(form.cleaned_data, {'new' : {}})
Back to Top