diff --git a/django/forms/forms.py b/django/forms/forms.py index 1400be30142..7818aac13a0 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -410,6 +410,16 @@ class BoundField(StrAndUnicode): return self.as_widget() + self.as_hidden(only_initial=True) return self.as_widget() + def __iter__(self): + """ + Yields rendered strings that comprise all widgets in this BoundField. + + This really is only useful for RadioSelect widgets, so that you can + iterate over individual radio buttons in a template. + """ + for subwidget in self.field.widget.subwidgets(self.html_name, self.value()): + yield self.as_widget(subwidget) + def _errors(self): """ Returns an ErrorList for this field. Returns an empty ErrorList diff --git a/django/forms/widgets.py b/django/forms/widgets.py index 57a6b4566a7..9c04750fdb2 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -156,6 +156,15 @@ class Widget(object): memo[id(self)] = obj return obj + def subwidgets(self, name, value, attrs=None, choices=()): + """ + Yields all "subwidgets" of this widget. Used only by RadioSelect to + allow template access to individual buttons. + + Arguments are the same as for render(). + """ + yield self + def render(self, name, value, attrs=None): """ Returns this Widget rendered as HTML, as a Unicode string. @@ -628,6 +637,12 @@ class RadioInput(StrAndUnicode): self.index = index def __unicode__(self): + return self.render() + + def render(self, name=None, value=None, attrs=None, choices=()): + name = name or self.name + value = value or self.value + attrs = attrs or self.attrs if 'id' in self.attrs: label_for = ' for="%s_%s"' % (self.attrs['id'], self.index) else: @@ -681,6 +696,10 @@ class RadioSelect(Select): self.renderer = renderer super(RadioSelect, self).__init__(*args, **kwargs) + def subwidgets(self, name, value, attrs=None, choices=()): + for widget in self.get_renderer(name, value, attrs, choices): + yield widget + def get_renderer(self, name, value, attrs=None, choices=()): """Returns an instance of the renderer.""" if value is None: value = '' diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt index 2b386c0864f..b657be4c534 100644 --- a/docs/ref/forms/widgets.txt +++ b/docs/ref/forms/widgets.txt @@ -345,7 +345,8 @@ commonly used groups of widgets: .. class:: RadioSelect - Similar to :class:`Select`, but rendered as a list of radio buttons: + Similar to :class:`Select`, but rendered as a list of radio buttons within + ``