Ticket #7664: 7664.diff

File 7664.diff, 3.7 KB (added by Koen Biermans, 8 years ago)

patch to allow passing names for widgets into MultiWidget

  • django/forms/widgets.py

    diff --git a/django/forms/widgets.py b/django/forms/widgets.py
    index 57a6b45..d4c48e9 100644
    a b class MultiWidget(Widget): 
    761761
    762762    You'll probably want to use this class with MultiValueField.
    763763    """
    764     def __init__(self, widgets, attrs=None):
     764    def __init__(self, widgets, attrs=None, names=None):
    765765        self.widgets = [isinstance(w, type) and w() or w for w in widgets]
     766        self.names = names
     767        if self.names:
     768            if len(self.names) != len(self.widgets):
     769                raise TypeError("The names argument for MultiWidget must be same length as the widgets list")
    766770        super(MultiWidget, self).__init__(attrs)
    767771
    768772    def render(self, name, value, attrs=None):
    class MultiWidget(Widget): 
    783787                widget_value = None
    784788            if id_:
    785789                final_attrs = dict(final_attrs, id='%s_%s' % (id_, i))
    786             output.append(widget.render(name + '_%s' % i, widget_value, final_attrs))
     790            widgetname = self.names and self.names[i] or i
     791            output.append(widget.render(name + '_%s' % widgetname, widget_value, final_attrs))
    787792        return mark_safe(self.format_output(output))
    788793
    789794    def id_for_label(self, id_):
    class MultiWidget(Widget): 
    794799    id_for_label = classmethod(id_for_label)
    795800
    796801    def value_from_datadict(self, data, files, name):
    797         return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
     802        values = []
     803        for i, widget in enumerate(self.widgets):
     804            widgetname = self.names and selfnames[i] or i
     805            values.append(widget.value_from_datadict(data, files, name + '_%s' % widgetname))
     806        return values
    798807
    799808    def _has_changed(self, initial, data):
    800809        if initial is None:
  • tests/regressiontests/forms/tests/widgets.py

    diff --git a/tests/regressiontests/forms/tests/widgets.py b/tests/regressiontests/forms/tests/widgets.py
    index ac78ad7..2850970 100644
    a b beatle J R Ringo False""") 
    887887        # short circuiting while testing the widgets.
    888888        self.assertTrue(w._has_changed(u'john__lennon', [u'john', u'denver']))
    889889
     890        # with explicit names for subwidgets
     891        w = MyMultiWidget(widgets=(TextInput(attrs={'class': 'big'}), TextInput(attrs={'class': 'small'})), names = ('big', 'small'))
     892        self.assertEqual(w.render('name', ['john', 'lennon']), u'<input type="text" class="big" value="john" name="name_big" /><br /><input type="text" class="small" value="lennon" name="name_small" />')
     893        self.assertEqual(w.render('name', 'john__lennon'), u'<input type="text" class="big" value="john" name="name_big" /><br /><input type="text" class="small" value="lennon" name="name_small" />')
     894        self.assertEqual(w.render('name', 'john__lennon', attrs={'id':'foo'}), u'<input id="foo_0" type="text" class="big" value="john" name="name_big" /><br /><input id="foo_1" type="text" class="small" value="lennon" name="name_small" />')
     895        w = MyMultiWidget(widgets=(TextInput(attrs={'class': 'big'}), TextInput(attrs={'class': 'small'})), attrs={'id': 'bar'}, names = ('big', 'small'))
     896        self.assertEqual(w.render('name', ['john', 'lennon']), u'<input id="bar_0" type="text" class="big" value="john" name="name_big" /><br /><input id="bar_1" type="text" class="small" value="lennon" name="name_small" />')
     897        self.assertRaises(TypeError, MyMultiWidget, widgets=(TextInput(), TextInput()), names=('big', 'middle', 'small'))
     898
    890899    def test_splitdatetime(self):
    891900        w = SplitDateTimeWidget()
    892901        self.assertEqual(w.render('date', ''), u'<input type="text" name="date_0" /><input type="text" name="date_1" />')
Back to Top