Opened 4 years ago

Closed 4 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: UI/UX:

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.']}

Change History (1)

comment:1 Changed 4 years ago by whardier

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to fixed
  • Status changed from new to closed

Setting the .widget.choices is not proper. Setting .choices is proper and propagates the list to the widget associated with the field.

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