Opened 19 years ago
Closed 19 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 , 19 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:2 by , 19 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Good catch!