Opened 6 years ago
Closed 6 years ago
#29921 closed Bug (invalid)
Default BooleanField.required different from Django 2.0 when using choices
Reported by: | Bogdan Batog | Owned by: | nobody |
---|---|---|---|
Component: | Forms | Version: | 2.1 |
Severity: | Normal | Keywords: | BooleanField, widget, required |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | yes |
Description
Using a BooleanField with choices inside a ModelForm, without explicit blank or null attributes on the model, exhibits different defaults for required attribute on the widget in Django2.1 vs Django2.0.
The code below prints True in Django2.1.2 and False in Django2.0.6
class XModel(models.Model): result_bool = models.BooleanField( choices=( (True, 'Positive'), (False, 'Negative'), ), default=False ) class XForm(forms.ModelForm): class Meta: model = XModel fields = ['result_bool'] XForm(XModel()).fields['result_bool'].required
Change History (3)
follow-up: 2 comment:1 by , 6 years ago
Type: | Uncategorized → Bug |
---|
comment:2 by , 6 years ago
Thanks for looking into it!
I did another experiment and simply commented out the choices lines. Now, in Django2.1.2, the code prints False while it printed True with the choices lines. This may be also expected, because it renders a different widget? To me it's surprising. I wouldn't expect the required attribute of a form field to change depending on the widget it will render.
It's also worth mentioning that Django2.0.6 is consistent and sets the field as not required both when using and not using choices.
comment:3 by , 6 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
Yes, it's expected because "required" for a checkbox input means "must be checked" while for a select input means "must have a value selected."
This looks like expected behavior to me. With the model you gave, a true or false value is required since the field can't be null, therefore the user must provide a value. I imagine your use case might be an API request where if the user didn't provide a value, a value of false was saved? Django doesn't normally fallback to a model field default if a value isn't provided to a form, but maybe this merits a mention in the release notes.
5fa4f40f45fcdbb7e48489ed3039a314b5c961d0 caused the change.