Loading django/forms/widgets.py +6 −7 Original line number Diff line number Diff line Loading @@ -753,20 +753,19 @@ class RendererMixin(object): self.renderer = renderer super(RendererMixin, self).__init__(*args, **kwargs) def subwidgets(self, name, value, attrs=None, choices=()): for widget in self.get_renderer(name, value, attrs, choices): def subwidgets(self, name, value, attrs=None): for widget in self.get_renderer(name, value, attrs): yield widget def get_renderer(self, name, value, attrs=None, choices=()): def get_renderer(self, name, value, attrs=None): """Returns an instance of the renderer.""" if value is None: value = self._empty_value final_attrs = self.build_attrs(attrs) choices = list(chain(self.choices, choices)) return self.renderer(name, value, final_attrs, choices) return self.renderer(name, value, final_attrs, self.choices) def render(self, name, value, attrs=None, choices=()): return self.get_renderer(name, value, attrs, choices).render() def render(self, name, value, attrs=None): return self.get_renderer(name, value, attrs).render() def id_for_label(self, id_): # Widgets using this RendererMixin are made of a collection of Loading tests/forms_tests/tests/test_widgets.py +32 −15 Original line number Diff line number Diff line Loading @@ -23,8 +23,8 @@ class FormsWidgetTests(SimpleTestCase): # RadioSelect uses a RadioFieldRenderer to render the individual radio inputs. # You can manipulate that object directly to customize the way the RadioSelect # is rendered. w = RadioSelect() r = w.get_renderer('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) w = RadioSelect(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) r = w.get_renderer('beatle', 'J') inp_set1 = [] inp_set2 = [] inp_set3 = [] Loading Loading @@ -62,8 +62,8 @@ beatle J G George False beatle J R Ringo False""") # A RadioFieldRenderer object also allows index access to individual RadioChoiceInput w = RadioSelect() r = w.get_renderer('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) w = RadioSelect(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) r = w.get_renderer('beatle', 'J') self.assertHTMLEqual(str(r[1]), '<label><input type="radio" name="beatle" value="P" /> Paul</label>') self.assertHTMLEqual( str(r[0]), Loading @@ -86,9 +86,9 @@ beatle J R Ringo False""") class MyRenderer(RadioFieldRenderer): def render(self): return '<br />\n'.join(six.text_type(choice) for choice in self) w = RadioSelect(renderer=MyRenderer) w = RadioSelect(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')), renderer=MyRenderer) self.assertHTMLEqual( w.render('beatle', 'G', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), w.render('beatle', 'G'), """<label><input type="radio" name="beatle" value="J" /> John</label><br /> <label><input type="radio" name="beatle" value="P" /> Paul</label><br /> <label><input checked="checked" type="radio" name="beatle" value="G" /> George</label><br /> Loading @@ -98,9 +98,9 @@ beatle J R Ringo False""") # Or you can use custom RadioSelect fields that use your custom renderer. class CustomRadioSelect(RadioSelect): renderer = MyRenderer w = CustomRadioSelect() w = CustomRadioSelect(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) self.assertHTMLEqual( w.render('beatle', 'G', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), w.render('beatle', 'G'), """<label><input type="radio" name="beatle" value="J" /> John</label><br /> <label><input type="radio" name="beatle" value="P" /> Paul</label><br /> <label><input checked="checked" type="radio" name="beatle" value="G" /> George</label><br /> Loading @@ -112,10 +112,8 @@ beatle J R Ringo False""") # str is just to test some Python 2 issue with bytestrings outer_html = str('<div{id_attr}>{content}</div>') inner_html = '<p>{choice_value}{sub_widgets}</p>' w = RadioSelect(renderer=MyRenderer) output = w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')), attrs={'id': 'bar'}) w = RadioSelect(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')), renderer=MyRenderer) output = w.render('beatle', 'J', attrs={'id': 'bar'}) self.assertIsInstance(output, SafeData) self.assertHTMLEqual( output, Loading @@ -128,17 +126,36 @@ beatle J R Ringo False""") def test_subwidget(self): # Each subwidget tag gets a separate ID when the widget has an ID specified self.assertHTMLEqual("\n".join(c.tag() for c in CheckboxSelectMultiple(attrs={'id': 'abc'}).subwidgets('letters', list('ac'), choices=zip(list('abc'), list('ABC')))), """<input checked="checked" type="checkbox" name="letters" value="a" id="abc_0" /> self.assertHTMLEqual( "\n".join( c.tag() for c in CheckboxSelectMultiple( attrs={'id': 'abc'}, choices=zip(list('abc'), list('ABC')) ).subwidgets('letters', list('ac')) ), """<input checked="checked" type="checkbox" name="letters" value="a" id="abc_0" /> <input type="checkbox" name="letters" value="b" id="abc_1" /> <input checked="checked" type="checkbox" name="letters" value="c" id="abc_2" />""") # Each subwidget tag does not get an ID if the widget does not have an ID specified self.assertHTMLEqual("\n".join(c.tag() for c in CheckboxSelectMultiple().subwidgets('letters', list('ac'), choices=zip(list('abc'), list('ABC')))), """<input checked="checked" type="checkbox" name="letters" value="a" /> self.assertHTMLEqual( "\n".join(c.tag() for c in CheckboxSelectMultiple( choices=zip(list('abc'), list('ABC')), ).subwidgets('letters', list('ac'))), """<input checked="checked" type="checkbox" name="letters" value="a" /> <input type="checkbox" name="letters" value="b" /> <input checked="checked" type="checkbox" name="letters" value="c" />""") # The id_for_label property of the subwidget should return the ID that is used on the subwidget's tag self.assertHTMLEqual("\n".join('<input type="checkbox" name="letters" value="%s" id="%s" />' % (c.choice_value, c.id_for_label) for c in CheckboxSelectMultiple(attrs={'id': 'abc'}).subwidgets('letters', [], choices=zip(list('abc'), list('ABC')))), """<input type="checkbox" name="letters" value="a" id="abc_0" /> self.assertHTMLEqual( "\n".join( '<input type="checkbox" name="letters" value="%s" id="%s" />' % (c.choice_value, c.id_for_label) for c in CheckboxSelectMultiple( attrs={'id': 'abc'}, choices=zip(list('abc'), list('ABC')), ).subwidgets('letters', []) ), """<input type="checkbox" name="letters" value="a" id="abc_0" /> <input type="checkbox" name="letters" value="b" id="abc_1" /> <input type="checkbox" name="letters" value="c" id="abc_2" />""") Loading tests/forms_tests/widget_tests/test_checkboxselectmultiple.py +9 −10 Original line number Diff line number Diff line Loading @@ -4,10 +4,10 @@ from .base import WidgetTest class CheckboxSelectMultipleTest(WidgetTest): widget = CheckboxSelectMultiple() widget = CheckboxSelectMultiple def test_render_value(self): self.check_html(self.widget, 'beatles', ['J'], choices=self.beatles, html=( self.check_html(self.widget(choices=self.beatles), 'beatles', ['J'], html=( """<ul> <li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li> <li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li> Loading @@ -17,7 +17,7 @@ class CheckboxSelectMultipleTest(WidgetTest): )) def test_render_value_multiple(self): self.check_html(self.widget, 'beatles', ['J', 'P'], choices=self.beatles, html=( self.check_html(self.widget(choices=self.beatles), 'beatles', ['J', 'P'], html=( """<ul> <li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li> <li><label><input checked="checked" type="checkbox" name="beatles" value="P" /> Paul</label></li> Loading @@ -30,7 +30,7 @@ class CheckboxSelectMultipleTest(WidgetTest): """ If the value is None, none of the options are selected. """ self.check_html(self.widget, 'beatles', None, choices=self.beatles, html=( self.check_html(self.widget(choices=self.beatles), 'beatles', None, html=( """<ul> <li><label><input type="checkbox" name="beatles" value="J" /> John</label></li> <li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li> Loading Loading @@ -73,8 +73,8 @@ class CheckboxSelectMultipleTest(WidgetTest): </ul> """ self.check_html( self.widget, 'nestchoice', ('vinyl', 'dvd'), choices=nested_choices, attrs={'id': 'media'}, html=html, self.widget(choices=nested_choices), 'nestchoice', ('vinyl', 'dvd'), attrs={'id': 'media'}, html=html, ) def test_separate_ids(self): Loading @@ -93,14 +93,13 @@ class CheckboxSelectMultipleTest(WidgetTest): </li> </ul> """ self.check_html(self.widget, 'letters', ['a', 'c'], choices=choices, attrs={'id': 'abc'}, html=html) self.check_html(self.widget(choices=choices), 'letters', ['a', 'c'], attrs={'id': 'abc'}, html=html) def test_separate_ids_constructor(self): """ Each input gets a separate ID when the ID is passed to the constructor. """ widget = CheckboxSelectMultiple(attrs={'id': 'abc'}) choices = [('a', 'A'), ('b', 'B'), ('c', 'C')] widget = CheckboxSelectMultiple(attrs={'id': 'abc'}, choices=[('a', 'A'), ('b', 'B'), ('c', 'C')]) html = """ <ul id="abc"> <li> Loading @@ -112,4 +111,4 @@ class CheckboxSelectMultipleTest(WidgetTest): </li> </ul> """ self.check_html(widget, 'letters', ['a', 'c'], choices=choices, html=html) self.check_html(widget, 'letters', ['a', 'c'], html=html) tests/forms_tests/widget_tests/test_radioselect.py +6 −6 Original line number Diff line number Diff line Loading @@ -4,10 +4,10 @@ from .base import WidgetTest class RadioSelectTest(WidgetTest): widget = RadioSelect() widget = RadioSelect def test_render(self): self.check_html(self.widget, 'beatle', 'J', choices=self.beatles, html=( self.check_html(self.widget(choices=self.beatles), 'beatle', 'J', html=( """<ul> <li><label><input checked="checked" type="radio" name="beatle" value="J" /> John</label></li> <li><label><input type="radio" name="beatle" value="P" /> Paul</label></li> Loading Loading @@ -44,7 +44,7 @@ class RadioSelectTest(WidgetTest): </ul> """ self.check_html( self.widget, 'nestchoice', 'dvd', choices=nested_choices, self.widget(choices=nested_choices), 'nestchoice', 'dvd', attrs={'id': 'media'}, html=html, ) Loading @@ -53,7 +53,7 @@ class RadioSelectTest(WidgetTest): Attributes provided at instantiation are passed to the constituent inputs. """ widget = RadioSelect(attrs={'id': 'foo'}) widget = RadioSelect(attrs={'id': 'foo'}, choices=self.beatles) html = """ <ul id="foo"> <li> Loading @@ -64,7 +64,7 @@ class RadioSelectTest(WidgetTest): <li><label for="foo_3"><input type="radio" id="foo_3" value="R" name="beatle" /> Ringo</label></li> </ul> """ self.check_html(widget, 'beatle', 'J', choices=self.beatles, html=html) self.check_html(widget, 'beatle', 'J', html=html) def test_render_attrs(self): """ Loading @@ -81,4 +81,4 @@ class RadioSelectTest(WidgetTest): <li><label for="bar_3"><input type="radio" id="bar_3" value="R" name="beatle" /> Ringo</label></li> </ul> """ self.check_html(self.widget, 'beatle', 'J', choices=self.beatles, attrs={'id': 'bar'}, html=html) self.check_html(self.widget(choices=self.beatles), 'beatle', 'J', attrs={'id': 'bar'}, html=html) Loading
django/forms/widgets.py +6 −7 Original line number Diff line number Diff line Loading @@ -753,20 +753,19 @@ class RendererMixin(object): self.renderer = renderer super(RendererMixin, self).__init__(*args, **kwargs) def subwidgets(self, name, value, attrs=None, choices=()): for widget in self.get_renderer(name, value, attrs, choices): def subwidgets(self, name, value, attrs=None): for widget in self.get_renderer(name, value, attrs): yield widget def get_renderer(self, name, value, attrs=None, choices=()): def get_renderer(self, name, value, attrs=None): """Returns an instance of the renderer.""" if value is None: value = self._empty_value final_attrs = self.build_attrs(attrs) choices = list(chain(self.choices, choices)) return self.renderer(name, value, final_attrs, choices) return self.renderer(name, value, final_attrs, self.choices) def render(self, name, value, attrs=None, choices=()): return self.get_renderer(name, value, attrs, choices).render() def render(self, name, value, attrs=None): return self.get_renderer(name, value, attrs).render() def id_for_label(self, id_): # Widgets using this RendererMixin are made of a collection of Loading
tests/forms_tests/tests/test_widgets.py +32 −15 Original line number Diff line number Diff line Loading @@ -23,8 +23,8 @@ class FormsWidgetTests(SimpleTestCase): # RadioSelect uses a RadioFieldRenderer to render the individual radio inputs. # You can manipulate that object directly to customize the way the RadioSelect # is rendered. w = RadioSelect() r = w.get_renderer('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) w = RadioSelect(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) r = w.get_renderer('beatle', 'J') inp_set1 = [] inp_set2 = [] inp_set3 = [] Loading Loading @@ -62,8 +62,8 @@ beatle J G George False beatle J R Ringo False""") # A RadioFieldRenderer object also allows index access to individual RadioChoiceInput w = RadioSelect() r = w.get_renderer('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) w = RadioSelect(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) r = w.get_renderer('beatle', 'J') self.assertHTMLEqual(str(r[1]), '<label><input type="radio" name="beatle" value="P" /> Paul</label>') self.assertHTMLEqual( str(r[0]), Loading @@ -86,9 +86,9 @@ beatle J R Ringo False""") class MyRenderer(RadioFieldRenderer): def render(self): return '<br />\n'.join(six.text_type(choice) for choice in self) w = RadioSelect(renderer=MyRenderer) w = RadioSelect(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')), renderer=MyRenderer) self.assertHTMLEqual( w.render('beatle', 'G', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), w.render('beatle', 'G'), """<label><input type="radio" name="beatle" value="J" /> John</label><br /> <label><input type="radio" name="beatle" value="P" /> Paul</label><br /> <label><input checked="checked" type="radio" name="beatle" value="G" /> George</label><br /> Loading @@ -98,9 +98,9 @@ beatle J R Ringo False""") # Or you can use custom RadioSelect fields that use your custom renderer. class CustomRadioSelect(RadioSelect): renderer = MyRenderer w = CustomRadioSelect() w = CustomRadioSelect(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))) self.assertHTMLEqual( w.render('beatle', 'G', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), w.render('beatle', 'G'), """<label><input type="radio" name="beatle" value="J" /> John</label><br /> <label><input type="radio" name="beatle" value="P" /> Paul</label><br /> <label><input checked="checked" type="radio" name="beatle" value="G" /> George</label><br /> Loading @@ -112,10 +112,8 @@ beatle J R Ringo False""") # str is just to test some Python 2 issue with bytestrings outer_html = str('<div{id_attr}>{content}</div>') inner_html = '<p>{choice_value}{sub_widgets}</p>' w = RadioSelect(renderer=MyRenderer) output = w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')), attrs={'id': 'bar'}) w = RadioSelect(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo')), renderer=MyRenderer) output = w.render('beatle', 'J', attrs={'id': 'bar'}) self.assertIsInstance(output, SafeData) self.assertHTMLEqual( output, Loading @@ -128,17 +126,36 @@ beatle J R Ringo False""") def test_subwidget(self): # Each subwidget tag gets a separate ID when the widget has an ID specified self.assertHTMLEqual("\n".join(c.tag() for c in CheckboxSelectMultiple(attrs={'id': 'abc'}).subwidgets('letters', list('ac'), choices=zip(list('abc'), list('ABC')))), """<input checked="checked" type="checkbox" name="letters" value="a" id="abc_0" /> self.assertHTMLEqual( "\n".join( c.tag() for c in CheckboxSelectMultiple( attrs={'id': 'abc'}, choices=zip(list('abc'), list('ABC')) ).subwidgets('letters', list('ac')) ), """<input checked="checked" type="checkbox" name="letters" value="a" id="abc_0" /> <input type="checkbox" name="letters" value="b" id="abc_1" /> <input checked="checked" type="checkbox" name="letters" value="c" id="abc_2" />""") # Each subwidget tag does not get an ID if the widget does not have an ID specified self.assertHTMLEqual("\n".join(c.tag() for c in CheckboxSelectMultiple().subwidgets('letters', list('ac'), choices=zip(list('abc'), list('ABC')))), """<input checked="checked" type="checkbox" name="letters" value="a" /> self.assertHTMLEqual( "\n".join(c.tag() for c in CheckboxSelectMultiple( choices=zip(list('abc'), list('ABC')), ).subwidgets('letters', list('ac'))), """<input checked="checked" type="checkbox" name="letters" value="a" /> <input type="checkbox" name="letters" value="b" /> <input checked="checked" type="checkbox" name="letters" value="c" />""") # The id_for_label property of the subwidget should return the ID that is used on the subwidget's tag self.assertHTMLEqual("\n".join('<input type="checkbox" name="letters" value="%s" id="%s" />' % (c.choice_value, c.id_for_label) for c in CheckboxSelectMultiple(attrs={'id': 'abc'}).subwidgets('letters', [], choices=zip(list('abc'), list('ABC')))), """<input type="checkbox" name="letters" value="a" id="abc_0" /> self.assertHTMLEqual( "\n".join( '<input type="checkbox" name="letters" value="%s" id="%s" />' % (c.choice_value, c.id_for_label) for c in CheckboxSelectMultiple( attrs={'id': 'abc'}, choices=zip(list('abc'), list('ABC')), ).subwidgets('letters', []) ), """<input type="checkbox" name="letters" value="a" id="abc_0" /> <input type="checkbox" name="letters" value="b" id="abc_1" /> <input type="checkbox" name="letters" value="c" id="abc_2" />""") Loading
tests/forms_tests/widget_tests/test_checkboxselectmultiple.py +9 −10 Original line number Diff line number Diff line Loading @@ -4,10 +4,10 @@ from .base import WidgetTest class CheckboxSelectMultipleTest(WidgetTest): widget = CheckboxSelectMultiple() widget = CheckboxSelectMultiple def test_render_value(self): self.check_html(self.widget, 'beatles', ['J'], choices=self.beatles, html=( self.check_html(self.widget(choices=self.beatles), 'beatles', ['J'], html=( """<ul> <li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li> <li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li> Loading @@ -17,7 +17,7 @@ class CheckboxSelectMultipleTest(WidgetTest): )) def test_render_value_multiple(self): self.check_html(self.widget, 'beatles', ['J', 'P'], choices=self.beatles, html=( self.check_html(self.widget(choices=self.beatles), 'beatles', ['J', 'P'], html=( """<ul> <li><label><input checked="checked" type="checkbox" name="beatles" value="J" /> John</label></li> <li><label><input checked="checked" type="checkbox" name="beatles" value="P" /> Paul</label></li> Loading @@ -30,7 +30,7 @@ class CheckboxSelectMultipleTest(WidgetTest): """ If the value is None, none of the options are selected. """ self.check_html(self.widget, 'beatles', None, choices=self.beatles, html=( self.check_html(self.widget(choices=self.beatles), 'beatles', None, html=( """<ul> <li><label><input type="checkbox" name="beatles" value="J" /> John</label></li> <li><label><input type="checkbox" name="beatles" value="P" /> Paul</label></li> Loading Loading @@ -73,8 +73,8 @@ class CheckboxSelectMultipleTest(WidgetTest): </ul> """ self.check_html( self.widget, 'nestchoice', ('vinyl', 'dvd'), choices=nested_choices, attrs={'id': 'media'}, html=html, self.widget(choices=nested_choices), 'nestchoice', ('vinyl', 'dvd'), attrs={'id': 'media'}, html=html, ) def test_separate_ids(self): Loading @@ -93,14 +93,13 @@ class CheckboxSelectMultipleTest(WidgetTest): </li> </ul> """ self.check_html(self.widget, 'letters', ['a', 'c'], choices=choices, attrs={'id': 'abc'}, html=html) self.check_html(self.widget(choices=choices), 'letters', ['a', 'c'], attrs={'id': 'abc'}, html=html) def test_separate_ids_constructor(self): """ Each input gets a separate ID when the ID is passed to the constructor. """ widget = CheckboxSelectMultiple(attrs={'id': 'abc'}) choices = [('a', 'A'), ('b', 'B'), ('c', 'C')] widget = CheckboxSelectMultiple(attrs={'id': 'abc'}, choices=[('a', 'A'), ('b', 'B'), ('c', 'C')]) html = """ <ul id="abc"> <li> Loading @@ -112,4 +111,4 @@ class CheckboxSelectMultipleTest(WidgetTest): </li> </ul> """ self.check_html(widget, 'letters', ['a', 'c'], choices=choices, html=html) self.check_html(widget, 'letters', ['a', 'c'], html=html)
tests/forms_tests/widget_tests/test_radioselect.py +6 −6 Original line number Diff line number Diff line Loading @@ -4,10 +4,10 @@ from .base import WidgetTest class RadioSelectTest(WidgetTest): widget = RadioSelect() widget = RadioSelect def test_render(self): self.check_html(self.widget, 'beatle', 'J', choices=self.beatles, html=( self.check_html(self.widget(choices=self.beatles), 'beatle', 'J', html=( """<ul> <li><label><input checked="checked" type="radio" name="beatle" value="J" /> John</label></li> <li><label><input type="radio" name="beatle" value="P" /> Paul</label></li> Loading Loading @@ -44,7 +44,7 @@ class RadioSelectTest(WidgetTest): </ul> """ self.check_html( self.widget, 'nestchoice', 'dvd', choices=nested_choices, self.widget(choices=nested_choices), 'nestchoice', 'dvd', attrs={'id': 'media'}, html=html, ) Loading @@ -53,7 +53,7 @@ class RadioSelectTest(WidgetTest): Attributes provided at instantiation are passed to the constituent inputs. """ widget = RadioSelect(attrs={'id': 'foo'}) widget = RadioSelect(attrs={'id': 'foo'}, choices=self.beatles) html = """ <ul id="foo"> <li> Loading @@ -64,7 +64,7 @@ class RadioSelectTest(WidgetTest): <li><label for="foo_3"><input type="radio" id="foo_3" value="R" name="beatle" /> Ringo</label></li> </ul> """ self.check_html(widget, 'beatle', 'J', choices=self.beatles, html=html) self.check_html(widget, 'beatle', 'J', html=html) def test_render_attrs(self): """ Loading @@ -81,4 +81,4 @@ class RadioSelectTest(WidgetTest): <li><label for="bar_3"><input type="radio" id="bar_3" value="R" name="beatle" /> Ringo</label></li> </ul> """ self.check_html(self.widget, 'beatle', 'J', choices=self.beatles, attrs={'id': 'bar'}, html=html) self.check_html(self.widget(choices=self.beatles), 'beatle', 'J', attrs={'id': 'bar'}, html=html)