Ticket #4136: iss_4136.diff

File iss_4136.diff, 3.2 KB (added by zefciu, 3 years ago)
  • django/forms/widgets.py

    diff --git a/django/forms/widgets.py b/django/forms/widgets.py
    index 49b148e..be7b895 100644
    a b __all__ = ( 
    2424    'FileInput', 'DateInput', 'DateTimeInput', 'TimeInput', 'Textarea', 'CheckboxInput',
    2525    'Select', 'NullBooleanSelect', 'SelectMultiple', 'RadioSelect',
    2626    'CheckboxSelectMultiple', 'MultiWidget',
    27     'SplitDateTimeWidget',
     27    'SplitDateTimeWidget', 'NullableWidget',
    2828)
    2929
    3030MEDIA_TYPES = ('css','js')
    class SplitHiddenDateTimeWidget(SplitDateTimeWidget): 
    900900        for widget in self.widgets:
    901901            widget.input_type = 'hidden'
    902902            widget.is_hidden = True
     903
     904class NullableWidget(MultiWidget):
     905    """
     906    A Widget that wraps another Widget and renders it along with a checkbox
     907    that unchecked means that the value should be None (NULL) [#4136]
     908    """
     909    def __init__(self, subwidget, attrs=None):
     910        self.checkbox = CheckboxInput()
     911        self.subwidget = subwidget
     912        super(NullableWidget, self).__init__(
     913            [self.checkbox, self.subwidget], attrs
     914        )
     915
     916    def decompress(self, value):
     917        if value is None:
     918            return [False, '']
     919        else:
     920            return [True, value]
     921
     922    def value_from_datadict(self, data, files, name):
     923        is_set, value = super(NullableWidget, self).value_from_datadict(
     924            data, files, name
     925        )
     926        if is_set:
     927            return value
     928        else:
     929            return None
  • tests/regressiontests/forms/tests/widgets.py

    diff --git a/tests/regressiontests/forms/tests/widgets.py b/tests/regressiontests/forms/tests/widgets.py
    index ce15b8b..54991b3 100644
    a b class ClearableFileInputTests(TestCase): 
    11891189                data={'myfile-clear': True},
    11901190                files={'myfile': f},
    11911191                name='myfile'), f)
     1192
     1193    def test_nullable_rendering(self):
     1194        """
     1195        Test if NullableWidget is rendered correctly.
     1196        """
     1197        w= NullableWidget(TextInput())
     1198        self.assertHTMLEqual(
     1199            w.render('email', ''),
     1200            u'<input type="checkbox" checked="checked" name="email_0" />'
     1201            u'<input type="text" name="email_1" />'
     1202        )
     1203        self.assertHTMLEqual(
     1204            w.render('email', 'test@example.com'),
     1205            u'<input type="checkbox" checked="checked" name="email_0" />'
     1206            u'<input type="text" name="email_1" value="test@example.com" />'
     1207        )
     1208        self.assertHTMLEqual(
     1209            w.render('email', None),
     1210            u'<input type="checkbox" name="email_0" />'
     1211            u'<input type="text" name="email_1" />'
     1212        )
     1213
     1214    def test_nullable_rendering(self):
     1215        """
     1216        Test if NullableWidget is rendered correctly.
     1217        """
     1218        w= NullableWidget(TextInput())
     1219        self.assertEqual(w.value_from_datadict(
     1220            data={'email_0': True, 'email_1': 'test@example.net'},
     1221            files={},
     1222            name='email'
     1223        ), 'test@example.net')
     1224       
     1225        self.assertEqual(w.value_from_datadict(
     1226            data={'email_0': False, 'email_1': 'test@example.net'},
     1227            files={},
     1228            name='email'
     1229        ), None)
Back to Top