﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
18829	ModelChoiceIterator doesn't adjust its length to account for an empty item.	facundo.olano@…	Klaas van Schelven	"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;
}}}"	Bug	closed	Forms	1.4	Normal	fixed	ModelChoiceIterator ModelForm		Accepted	1	0	0	0	1	0
