Opened 18 years ago

Closed 18 years ago

Last modified 18 years ago

#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)

iterator_choices.patch (1.4 KB ) - added by Alex Dedul 18 years ago.
iterator_choices_try2.patch (2.2 KB ) - added by Alex Dedul 18 years ago.

Download all attachments as: .zip

Change History (7)

by Alex Dedul, 18 years ago

Attachment: iterator_choices.patch added

comment:1 by Malcolm Tredinnick, 18 years ago

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).

comment:2 by Alex Dedul, 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:

  1. Cache values.
  2. Lazy fetching.

itertools.tee does exactly that.

comment:3 by Adrian Holovaty, 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 Alex Dedul, 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 Alex Dedul, 18 years ago

Attachment: iterator_choices_try2.patch added

comment:5 by Malcolm Tredinnick, 18 years ago

Resolution: fixed
Status: newclosed

(In [3851]) Fixed #2265 -- Fixed problem with using iterators for "choices" attribute.
Thanks, Alex Dedul.

Note: See TracTickets for help on using tickets.
Back to Top