#18829: ModelChoiceIterator returns the queryset length when
-------------------------------+-------------------------------------------
Reporter: | Owner: nobody
facundo.olano@… | Status: new
Type: Bug | Version: 1.4
Component: Forms | Keywords: ModelChoiceIterator ModelForm
Severity: Normal | Has patch: 0
Triage Stage: Unreviewed | UI/UX: 0
Easy pickings: 0 |
-------------------------------+-------------------------------------------
In forms/models.py, the ModelChoiceIterator defines an {{{ __iter__ }}}
method which yields an empty entry {{{ if empty_label is not None}}}, but
the {{{ __len__ }}} method always returns the length of the queryset, no
matter if the empty choice is present.
{{{
def __iter__(self):
if self.field.empty_label is not None:
yield (u"", self.field.empty_label)
if self.field.cache_choices:
if self.field.choice_cache is None:
self.field.choice_cache = [
self.choice(obj) for obj in self.queryset.all()
]
for choice in self.field.choice_cache:
yield choice
else:
for obj in self.queryset.all():
yield self.choice(obj)
def __len__(self):
return len(self.queryset)
}}}
This can lead to erratic behavior when iterating. For example, the
following template code wont hold the expected output, because the
forloop.last will be True before for the second to last item, causing the
semicolon to render on the last line and not in the previous one.
{{{
{% for choice_id, choice_name in my_form.my_field.field.choices %}
{{ choice_id }} - {{ choice_name }} {% if not forloop.last %};{% endif
%}
{% endfor %}
}}}
This would produce an output like:
{{{
- -----;
1 - One;
2 - Two
3 - Three;
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/18829>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit https://groups.google.com/groups/opt_out.