#3482 closed Bug (wontfix)
MultipleChoiceField validation against a list with a single null element
| Reported by: | Owned by: | nobody | |
|---|---|---|---|
| Component: | Forms | Version: | dev |
| Severity: | Normal | 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
MultipleChoiceField fails validation when required=False against a list with a single null value (as opposed to when value itself is null)
>>> f = MultipleChoiceField(required=False, choices=[('1', '1'), ('2', '2')])
>>> f.clean([''])
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "django/newforms/fields.py", line 386, in clean
if val not in valid_values:
django.newforms.util.ValidationError: [u'Select a valid choice. is not one of the available choices.']
>>>
Attachments (2)
Change History (9)
by , 19 years ago
comment:1 by , 19 years ago
| Triage Stage: | Unreviewed → Design decision needed |
|---|
comment:2 by , 19 years ago
New patch. Clean now returns an empty list rather than the original value.
comment:3 by , 18 years ago
| Triage Stage: | Design decision needed → Ready for checkin |
|---|
comment:4 by , 18 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
This has already been fixed at some point in the interim (and we're testing it).
comment:5 by , 4 years ago
| Easy pickings: | unset |
|---|---|
| Resolution: | fixed |
| Severity: | → Normal |
| Status: | closed → new |
| Type: | → Uncategorized |
| UI/UX: | unset |
This is still happening for me in Django 3.1.13:
>>> from django.forms import MultipleChoiceField
>>> f = MultipleChoiceField(required=False, choices=[('1', '1'), ('2', '2')])
>>> f.clean([''])
Traceback (most recent call last):
File "/Users/joshsmith/.pyenv/versions/3.9.4/lib/python3.9/code.py", line 90, in runcode
exec(code, self.locals)
File "<console>", line 1, in <module>
File "/Users/joshsmith/code/course-platform/.venv/lib/python3.9/site-packages/django/forms/fields.py", line 150, in clean
self.validate(value)
File "/Users/joshsmith/code/course-platform/.venv/lib/python3.9/site-packages/django/forms/fields.py", line 883, in validate
raise ValidationError(
django.core.exceptions.ValidationError: ['Select a valid choice. is not one of the available choices.']
comment:6 by , 4 years ago
| Has patch: | unset |
|---|---|
| Triage Stage: | Ready for checkin → Unreviewed |
| Type: | Uncategorized → Bug |
comment:7 by , 4 years ago
| Resolution: | → wontfix |
|---|---|
| Status: | new → closed |
So, it's hard to say about the dark-history here, as bootstrapping a very old environment is somewhat fiddly these days but the logic here is virtually unchanged from the earliest days of the MultipleChoiceField implementation. It's certainly unchanged as far back as Django 1.8. Without a serious case being made, the backwards compatibility concerns preclude changing this now.
However, for me, this is expected behaviour: '' is not a valid choice. If I want filtering of empty values then I'm expecting to use a widget to filter this in value_from_datadict, or else a field subclass, if I want the behaviour there. The default implementation is doing the right thing here rejecting the incorrect value.
In your example, shouldn't
f.clean([''])return[]rather than['']?