#23580 closed Uncategorized (invalid)
forms.fields.NullBooleanField does not honor required=True
Reported by: | Jon Dufresne | Owned by: | nobody |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | jon.dufresne@… | Triage Stage: | Unreviewed |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I use forms.fields.NullBooleanField
to allow a user to select Yes, No or Unknown (Unknown may also mean "no answer"). Sometimes -- depending on the site configuration -- this field should be required, other times not. In this case, required means that either Yes or No should be selected. The field should *not* be left blank (Unknown or "no answer"). Currently, when required=True
is set, forms.fields.NullBooleanField.validate()
does nothing and will simply validate all values.
I can't use forms.fields.BooleanField
because when required=True
is set Yes *must* be selected for the field to validate.
This topic has come up in the past: <https://groups.google.com/d/msg/django-developers/eN7FvAvTsew/kLQ4FdE3fWAJ>
I propose forms.fields.NullBooleanField
be altered to handle required. That is change validate to:
def validate(self, value): if value is None and self.required: raise ValidationError(....
I'll happily create a pull request to achieve this. One concern will be backwards compatibility. But seeing as how required=True
had no effect on the field originally, I see no reason anyone would set it and expect something useful other than what has been suggested above.
Change History (8)
comment:1 by , 10 years ago
Cc: | added |
---|---|
Has patch: | set |
comment:2 by , 10 years ago
What would then be the difference between your proposal (forms.fields.NullBooleanField
with required=True
) and forms.fields.BooleanField
with required=False
?
comment:3 by , 10 years ago
I think the primary difference is the widget used. In the case of NullBooleanField
, you get a <select>
where the user must pick True
or False
, whereas BooleanField
is a checkbox where no explicit selection must be made.
The fix for #23130 may address the use case of this ticket.
comment:4 by , 10 years ago
What would then be the difference between your proposal (forms.fields.NullBooleanField with required=True) and forms.fields.BooleanField with required=False?
forms.fields.BooleanField
does not allow for a "no answer". In my application the user must *explicitly* select Yes or No. Assuming No when no answer is provided is not an option.
Just for some clarification, I'm rendering this field as a yes/no radio option:
This field is required. Do you agree with foo? [ ] Yes [ ] No
With my proposal above, the user would need to explicitly select No for the field to evaluate as False
, if the field is required and and they do not select No, they will be warned.
comment:5 by , 10 years ago
The fix for #23130 may address the use case of this ticket.
If I understand that ticket correctly (and perhaps I don't) that looks to be dealing with the model layer and how it creates forms in the admin site. Is this correct?
My use case has no connection to models nor the admin site. This is just a straight form POST to a view with validating and processing that data.
comment:6 by , 10 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
I don't think excluding the validity of the Unknown
choice when required=True
is a good idea at all.
I think that your use case is fulfilled by something like:
forms.ChoiceField(widget=forms.RadioSelect, choices=((1, 'Yes'), (0, 'No')), required=True)
comment:7 by , 10 years ago
think that your use case is fulfilled by something like:
forms.ChoiceField(widget=forms.RadioSelect, choices=((1, 'Yes'), (0, 'No')), required=True)
One of the issues with this, it evaluates to the string '1'
and '0'
(or 'True'
and 'False'
) and not the values: True
, False
, None
as the NullBooleanField
does. I think that is the major downside here.
So in the end, a custom field and widget is required by the application writer for something that seems very simple on the surface. That is, a boolean form field that does not default to False
and must be answered either True
/False
.
Obviously one can always add this into their own project -- and maybe my proposal is the incorrect approach -- but I still think it would be nice to have something to accomplish this built-in.
comment:8 by , 10 years ago
This might be a topic for a django-developers discussion, to see if you can get some traction for your suggestion.
Submitted pull required: <https://github.com/django/django/pull/3297>