#23681: NullBooleanSelect should have choices kwarg
-----------------------------+--------------------------------------
Reporter: benjaoming | Owner: benjaoming
Type: New feature | Status: assigned
Component: Forms | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-----------------------------+--------------------------------------
Old description:
> `NullBooleanSelect` is responsible of making the values 1, 2, and 3 turn
> into None, True or False. That's very nice of it, however it does not
> allow to customize the texts of the choices.
>
> I'm not sure if exposing the internal 1, 2, 3 representation is a good
> idea, but it would seem okay since it follows the convention of other
> Select widgets. Ideally, I would like to see this...
>
> {{{
> class NullBooleanSelect(Select):
> """
> A Select Widget intended to be used with NullBooleanField.
> """
> def __init__(self, attrs=None):
> choices = (('1', ugettext_lazy('Unknown')),
> ('2', ugettext_lazy('Yes')),
> ('3', ugettext_lazy('No')))
> super(NullBooleanSelect, self).__init__(attrs, choices)
> }}}
>
> ...changed to:
>
> {{{
> class NullBooleanSelect(Select):
> """
> A Select Widget intended to be used with NullBooleanField.
> """
> def __init__(self, choices=None, attrs=None):
> if not choices:
> choices = (('1', empty_label or ugettext_lazy('Unknown')),
> ('2', ugettext_lazy('Yes')),
> ('3', ugettext_lazy('No')))
> super(NullBooleanSelect, self).__init__(attrs, choices)
> }}}
>
> The motivation is that I often leave out labels to have them put as the
> default first option of the Select. An example use:
>
> {{{
> class MyForm(forms.Form):
> gender = forms.NullBooleanField(
> label="",
> required=False,
> widget=NullBooleanSelect(choices=[("1", "Male and female"),
> ("2", "Only female"),
> ("3", "Only Male")])
> help_text=_(u"Only show subscriptions that have previously been
> charged"),
> )
>
> }}}
>
> Even more preferable, would be to place the `choices` kwarg in
> `NullBooleanField`, as that would match the options for ChoiceField.
>
> <b>Updated</b> In the original issue report, I put `empty_label` but
> realized that when selecting "Yes", it was impossible for the user to see
> what "Yes" was the answer to.
New description:
`NullBooleanSelect` is responsible of making the values 1, 2, and 3 turn
into None, True or False. That's very nice of it, however it does not
allow to customize the texts of the choices.
I'm not sure if exposing the internal 1, 2, 3 representation is a good
idea, but it would seem okay since it follows the convention of other
Select widgets. Ideally, I would like to see this...
{{{
class NullBooleanSelect(Select):
"""
A Select Widget intended to be used with NullBooleanField.
"""
def __init__(self, attrs=None):
choices = (('1', ugettext_lazy('Unknown')),
('2', ugettext_lazy('Yes')),
('3', ugettext_lazy('No')))
super(NullBooleanSelect, self).__init__(attrs, choices)
}}}
...changed to:
{{{
class NullBooleanSelect(Select):
"""
A Select Widget intended to be used with NullBooleanField.
"""
def __init__(self, choices=None, attrs=None):
if not choices:
choices = (('1', empty_label or ugettext_lazy('Unknown')),
('2', ugettext_lazy('Yes')),
('3', ugettext_lazy('No')))
super(NullBooleanSelect, self).__init__(attrs, choices)
}}}
The motivation is that I often leave out labels to have them put as the
default first option of the Select. An example use:
{{{
class MyForm(forms.Form):
gender = forms.NullBooleanField(
label="",
required=False,
widget=NullBooleanSelect(choices=[("1", "Male and female"),
("2", "Only female"),
("3", "Only Male")])
help_text="Choose gender",
)
}}}
Even more preferable, would be to place the `choices` kwarg in
`NullBooleanField`, as that would match the options for ChoiceField.
<b>Updated</b> In the original issue report, I put `empty_label` but
realized that when selecting "Yes", it was impossible for the user to see
what "Yes" was the answer to.
--
Comment (by benjaoming):
Hi timgraham! I think what you are hinting at is this:
{{{
class MyForm(forms.Form):
gender = forms.NullBooleanField(
label="",
required=False,
widget=Select(choices=[("1", "Male and female"),
("2", "Only female"),
("3", "Only Male")])
help_text="Choose gender",
)
}}}
It will work, but not perfectly. `NullBooleanSelect` has special methods
`render`, `value_from_datadict` that are tailored for NullBooleanField
(I'm not sure why `_has_changed` has gone, it used to also be customized).
As I understand, they are there to ensure that the `None` value can be
deliberately extracted from the value '1'.
I'm totally open for suggestions... I would like to be able to achieve
custom labels in the choices of `NullBooleanField`, because I think it's
an essential option that can keep us from creating one-trick sub classes.
And I would probably often like to use other words than Unknown, Yes, and
No.
Seeing that `NullBooleanField` '''always''' returns None, False, and True,
it might make sense to put them as explicit kwargs, like how `empty_label`
is used. This is perhaps better than using the widget....
{{{
class MyForm(forms.Form):
gender = forms.NullBooleanField(
label="",
required=False,
empty_label="Male and female",
true_label="Only female",
false_label="Only Male",
help_text="Choose gender",
)
}}}
To me, that seems nice, clean, explicit, and useful :) And yes, I can
write a patch!
--
Ticket URL: <https://code.djangoproject.com/ticket/23681#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/068.2ad04ef8c687906ebc4bad254c994dcb%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.