Opened 10 months ago

Last modified 10 months ago

#35126 closed Bug

forms.NullBooleanField's validation logic is surprising — at Version 1

Reported by: Jeremy Lainé Owned by: nobody
Component: Forms Version: 5.0
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 Jeremy Lainé)

Reading NullBooleanField's code lead me to believe that it would clean "1" to True, and "0" to False", just like BooleanField does:

https://github.com/django/django/blob/10c7c7320baf1c655fcb91202169d77725c9c4bd/django/forms/fields.py#L850

A simple field-level test works:

>>> from django import forms
>>> field = forms.NullBooleanField()
>>> field.clean("1")
True
>>> field.clean("0")
False

But using this in an actual form fails, note the difference between the BooleanField and NullBooleanField:

>>> class DemoForm(forms.Form):
...    field_a = forms.BooleanField()
...    field_b = forms.NullBooleanField()
...
>>> form = DemoForm({"field_a": "1", "field_b": "1"})
>>> form.is_valid()
>>> form.cleaned_data
{'field_a': True, 'field_b': None}

The problem is that by default NullBooleanField uses a NullBooleanSelect which mangles the submitted data for some obscure backwards-compatibility reason:

https://github.com/django/django/blob/10c7c7320baf1c655fcb91202169d77725c9c4bd/django/forms/widgets.py#L816

Change History (1)

comment:1 by Jeremy Lainé, 10 months ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top