#2265 closed defect (fixed)
[patch] Field's choices can be "used" only once if its a generator or an iterator.
Reported by: | Alex Dedul | Owned by: | Adrian Holovaty |
---|---|---|---|
Component: | Core (Other) | Version: | |
Severity: | normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
If you have field with an iterator/generator for choices its correct display value could be fetched only once. For example:
>>> from intranet.orders.models import SSL >>> s = SSL.objects.get(pk=1) >>> s.get_country_display() 'Belarus' >>> s.get_country_display() 'BY' >>> s.get_country_display() 'BY'
Its apparent that its because of the nature of iterators that can be "listed" only once. Proposed patch to fix this uses itertools.tee for every field.choices that looks like an iterator. Hardly its perfect, cos tee is caching values. Maybe someone could come up with a better solution.
Also there should be tests for this, but lets see what core devs says for now.
Attachments (2)
Change History (7)
by , 18 years ago
Attachment: | iterator_choices.patch added |
---|
comment:1 by , 18 years ago
comment:2 by , 18 years ago
As for me i'm using generator to fetch choices list from DB on external host and advanges of lazy fetching should be seen quite well here.
As for itertools.tee replacement self.choices = list(choices) is no go, list() fetches values from iterator right away. What we need from fix is:
- Cache values.
- Lazy fetching.
itertools.tee does exactly that.
comment:3 by , 18 years ago
Alex -- Given that itertools.tee
is not available in Python 2.3, do you have an idea for another solution?
comment:4 by , 18 years ago
As it turns out there is already implementation of tee() for python 2.3 http://www.python.org/doc/2.3.5/lib/itertools-example.html . Attached another version of patch based on that code.
by , 18 years ago
Attachment: | iterator_choices_try2.patch added |
---|
comment:5 by , 18 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
All Django code must be Python 2.3 compatible and
itertools.tee
was only introduced in Python 2.4.Also, why not just do
self.choices = list(choices)
if you want to cache the values? The iterator interface supports coercing to a list. Am I missing something tricky (besides completely defeating the purpose of using an iterator in the first place; but not being able to use it more than once seems like an even bigger bug).