Opened 15 years ago
Closed 15 years ago
#15581 closed (fixed)
MultipleChoiceInput not validating choices set after field definition (with example)
| Reported by: | whardier | Owned by: | nobody |
|---|---|---|---|
| Component: | Forms | Version: | 1.3-alpha |
| Severity: | Keywords: | MultipleChoiceField | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
It appears as though some validation is being done as a Field is instantiated.. or the choices are not being migrated to a variable used for validation later on per class. I'm hoping to discover the reason behind this not working as expected.
In the example below I am setting choices for a MultipleChoiceField after creating the field instance 'creators':
>>> TestForm = forms.Form(data={u'creators': [u'12', u'7']})
>>> TestForm.fields['creators'] = forms.MultipleChoiceField()
>>> TestForm.fields['creators'].widget.choices = [(x.id, unicode(x)) for x in User.objects.filter(submission__survey=1).distinct()]
>>> for choice in TestForm.fields['creators'].widget.choices:
... print choice
...
(6L, u'jeffspencer')
(1L, u'shanespencer')
(12L, u'kjohnson')
(10L, u'plomonaco')
(7L, u'shanestewart')
(13L, u'dtollison')
(11L, u'khaney')
(16L, u'mbritt')
(14L, u'roberteoll')
(9L, u'thomasdunlap')
(18L, u'jsmith')
(22L, u'willeagle')
(15L, u'mlaselle')
>>> TestForm.is_valid()
False
>>> TestForm.errors
{'creators': [u'Select a valid choice. 12 is not one of the available choices.']}
In this working example I am using ModelMultipleChoiceField and a queryset to set up the choices of field 'creators' instace immediately. This works the same if I set the queryset later on and use a broader filter for the User model initially.
>>> TestForm = forms.Form(data={u'creators': [u'12', u'7']})
>>> TestForm.fields['creators'] = forms.ModelMultipleChoiceField(queryset=User.objects.filter(submission__survey=1).distinct())
>>> for choice in TestForm.fields['creators'].widget.choices:
... print choice
...
(6L, u'jeffspencer')
(1L, u'shanespencer')
(12L, u'kjohnson')
(10L, u'plomonaco')
(7L, u'shanestewart')
(13L, u'dtollison')
(11L, u'khaney')
(16L, u'mbritt')
(14L, u'roberteoll')
(9L, u'thomasdunlap')
(18L, u'jsmith')
(22L, u'willeagle')
(15L, u'mlaselle')
>>> TestForm.is_valid()
True
In this working example I am using MultipleChoiceField again but setting the choices of the 'creators' field instance immediately.
>>> TestForm = forms.Form(data={u'creators': [u'12', u'7']})
>>> TestForm.fields['creators'] = forms.MultipleChoiceField(choices=[(12, 'hi'), ('7', 'sup')])
>>> for choice in TestForm.fields['creators'].widget.choices:
... print choice
...
(12, 'hi')
('7', 'sup')
>>> TestForm.is_valid()
True
Alternatively setting the choices in afterwords with the previous example (removing any query mistakes) gives similar results to the original problem.
>>> TestForm = forms.Form(data={u'creators': [u'12', u'7']})
>>> TestForm.fields['creators'] = forms.MultipleChoiceField()
>>> TestForm.fields['creators'].widget.choices = [(12, 'hi'), ('7', 'sup')]
>>> TestForm.is_valid()
False
>>> TestForm.errors
{'creators': [u'Select a valid choice. 12 is not one of the available choices.']}
Setting the .widget.choices is not proper. Setting .choices is proper and propagates the list to the widget associated with the field.