Opened 18 years ago
Closed 18 years ago
#3300 closed defect (fixed)
newforms Select widget only renders choices once when using generator
Reported by: | Owned by: | Adrian Holovaty | |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | normal | Keywords: | newforms Select widget |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The newforms Select widget (newforms.django.widgets.Select) only renders the select list choices on the first call when using a generator for the choices constructor argument. Here's an example adapted from tests/regressiontests/forms/tests.py:
>>> def get_choices(): ... for i in range(5): ... yield (i, i) >>> w = Select(choices=get_choices()) >>> print w.render('num',2) <select name="num"> <option value="0">0</option> <option value="1">1</option> <option value="2" selected="selected">2</option> <option value="3">3</option> <option value="4">4</option> </select> >>> print w.render('num',2) <select name="num"> </select>
Platform: Python v. 2.4.3 on cygwin
I think this problem occurs because a generator object created by a generator function or a generator expression can only be iterated over once.
A work-around is to create a sequence type from the generator:
>>> def get_choices(): ... for i in range(5): ... yield (i, i) >>> w = Select(choices=tuple(get_choices())) >>> print w.render('num',2) <select name="num"> <option value="0">0</option> <option value="1">1</option> <option value="2" selected="selected">2</option> <option value="3">3</option> <option value="4">4</option> </select> >>> print w.render('num',2) <select name="num"> <option value="0">0</option> <option value="1">1</option> <option value="2" selected="selected">2</option> <option value="3">3</option> <option value="4">4</option> </select>
The documentation should either state that the choices argument to Select.init() should not be a generator, or the widget should convert the generator object to a sequence and save a copy so that the behavior of Select.render() is consistent regardless of how many times it is called.
Change History (2)
comment:1 by , 18 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:2 by , 18 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Good catch!