diff --git a/django/newforms/widgets.py b/django/newforms/widgets.py index c71810465e7..3c27f7e2c11 100644 --- a/django/newforms/widgets.py +++ b/django/newforms/widgets.py @@ -136,9 +136,11 @@ class CheckboxInput(Widget): class Select(Widget): def __init__(self, attrs=None, choices=()): - # choices can be any iterable self.attrs = attrs or {} - self.choices = choices + # choices can be any iterable, but we may need to render this widget + # multiple times. Thus, collapse it into a list so it can be consumed + # more than once. + self.choices = list(choices) def render(self, name, value, attrs=None, choices=()): if value is None: value = '' diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index 95e8b59c019..328582d162a 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -336,6 +336,26 @@ If 'choices' is passed to both the constructor and render(), then they'll both b >>> w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]) u'' +If choices is passed to the constructor and is a generator, it can be iterated +over multiple times without getting consumed: +>>> w = Select(choices=get_choices()) +>>> print w.render('num', 2) + +>>> print w.render('num', 3) + + # NullBooleanSelect Widget #################################################### >>> w = NullBooleanSelect()