Opened 16 months ago
Last modified 16 months ago
#34721 closed Bug
ChoiceField/TypedChoiceField: .value() has inconsistent behaviour, coercion not applied. — at Version 1
Reported by: | Daniel | Owned by: | nobody |
---|---|---|---|
Component: | Forms | Version: | 4.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Given a form like
# forms.py class MyForm(Form): colour = ChoiceField( choices=[(0, "Red"), (1, "Green"), (2, "Blue"), (3, "Yellow")], initial=0, widget=HiddenInput(), required=True, ) # views.py def my_view(request): my_form = MyForm(request.POST or None) ... return render(request,"template.html", { "my_form": my_form })
and a template like
{% for colour_id, colour in my_form.fields.colour.choices %} {{ colour }}: {% if colour_id == my_form.colour.value %}selected{% else %}not selected{% endif %} {% endfor %}
I find inconsistent behaviour in the return type of my_form["colour"]
, or {{ my_form.colour.value }}
respectively.
my_form.fields["colour"].choices
, and {{ my_form.fields.colour.choices }}
correctly return the list of tuples assigned to the choices=
parameter of the ChoiceField
, retaining their types. Hence, colour_id
and colour
are of type int
and string
respectively.
If the form is unbound and the fields initial=
value is used, then my_form["colour"]
, and {{ my_form.colour.value }}
return the initial value of 0
as type int
.
If the form is bound, then my_form["colour"]
, and {{ my_form.colour.value }}
return the selected choice as type str
.
I would expect that all, my_form.fields["colour"].choices
and {{ my_form.fields.colour.choices }}
and my_form["colour"]
and {{ my_form.colour.value }}
would return the values as the same type.
Changing ChoiceField(...)
to TypedChoiceField(..., coerce=int)
does only affect my_form.cleaned_data["colour"]
, but neither of my_form.fields["colour"].choices
,{{ my_form.fields.colour.choices }}
, or my_form["colour"]
, or{{ my_form.colour.value }}
.
Ultimately leads to {% if colour_id == my_form.colour.value %}
never being true when the form is bound, even when it should.