Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#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 Jon Dufresne, 10 years ago

Cc: jon.dufresne@… added
Has patch: set

comment:2 by Claude Paroz, 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 Tim Graham, 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 Jon Dufresne, 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 Jon Dufresne, 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 Claude Paroz, 10 years ago

Resolution: invalid
Status: newclosed

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 Jon Dufresne, 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 Claude Paroz, 10 years ago

This might be a topic for a django-developers discussion, to see if you can get some traction for your suggestion.

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