Ticket #5828: 6614_is_empty_fix.diff

File 6614_is_empty_fix.diff, 4.5 KB (added by brosner, 7 years ago)

adds an is_empty to widget classes w/tests.

  • django/newforms/forms.py

    === django/newforms/forms.py
    ==================================================================
     
    189189        for name, field in self.fields.items():
    190190            if name in exceptions:
    191191                continue
    192             # value_from_datadict() gets the data from the dictionary.
     192            # value_from_datadict() gets the data from the data dictionaries.
    193193            # Each widget type knows how to retrieve its own data, because some
    194194            # widgets split data over several HTML fields.
    195195            value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
    196             # HACK: ['', ''] and [None, None] deal with SplitDateTimeWidget. This should be more robust.
    197             if value not in (None, '', ['', ''], [None, None]):
     196            if not field.widget.is_empty(value):
    198197                return False
    199198        return True
    200199
  • django/newforms/widgets.py

    === django/newforms/widgets.py
    ==================================================================
     
    164164        of this widget. Returns None if it's not provided.
    165165        """
    166166        return data.get(name, None)
     167   
     168    def is_empty(self, value):
     169        """
     170        Given a dictionary of data and this widget's name, return True if the
     171        widget data is empty or False when not empty.
     172        """
     173        if value not in (None, ''):
     174            return False
     175        return True
    167176
    168177    def id_for_label(self, id_):
    169178        """
     
    294303            # send results for unselected checkboxes.
    295304            return False
    296305        return super(CheckboxInput, self).value_from_datadict(data, files, name)
     306   
     307    def is_empty(self, value):
     308        # this widget will always either be True or False, so always return the
     309        # opposite value so False values will make the form empty
     310        return not value
    297311
    298312class Select(Widget):
    299313    def __init__(self, attrs=None, choices=()):
     
    333347    def value_from_datadict(self, data, files, name):
    334348        value = data.get(name, None)
    335349        return {u'2': True, u'3': False, True: True, False: False}.get(value, None)
     350   
     351    def is_empty(self, value):
     352        # this widget will always either be True, False or None, so always
     353        # return the opposite value so False and None values will make the
     354        # form empty.
     355        return not value
    336356
    337357class SelectMultiple(Widget):
    338358    def __init__(self, attrs=None, choices=()):
     
    521541
    522542    def value_from_datadict(self, data, files, name):
    523543        return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
     544   
     545    def is_empty(self, value):
     546        for widget, val in zip(self.widgets, value):
     547            if not widget.is_empty(val):
     548                return False
     549        return True
    524550
    525551    def format_output(self, rendered_widgets):
    526552        """
  • tests/regressiontests/forms/widgets.py

    === tests/regressiontests/forms/widgets.py
    ==================================================================
     
    282282>>> w.value_from_datadict({}, {}, 'testing')
    283283False
    284284
     285The CheckboxInput widget will always be empty when there is a False value
     286>>> w.is_empty(False)
     287True
     288>>> w.is_empty(True)
     289False
     290
    285291# Select Widget ###############################################################
    286292
    287293>>> w = Select()
     
    432438<option value="3" selected="selected">No</option>
    433439</select>
    434440
     441The NullBooleanSelect widget will always be empty when Unknown or No is selected
     442as its value.  This is to stay compliant with the CheckboxInput behavior
     443>>> w.is_empty(False)
     444True
     445>>> w.is_empty(None)
     446True
     447>>> w.is_empty(True)
     448False
     449
    435450""" + \
    436451r""" # [This concatenation is to keep the string below the jython's 32K limit].
    437452# SelectMultiple Widget #######################################################
     
    834849>>> w.render('name', ['john', 'lennon'])
    835850u'<input id="bar_0" type="text" class="big" value="john" name="name_0" /><br /><input id="bar_1" type="text" class="small" value="lennon" name="name_1" />'
    836851
     852The MultiWidget will be empty only when all widgets are considered empty.
     853>>> w.is_empty(['john', 'lennon'])
     854False
     855>>> w.is_empty(['john', ''])
     856False
     857>>> w.is_empty(['', ''])
     858True
     859>>> w.is_empty([None, None])
     860True
     861
    837862# SplitDateTimeWidget #########################################################
    838863
    839864>>> w = SplitDateTimeWidget()
Back to Top