Opened 4 years ago

Closed 4 years ago

#31971 closed New feature (wontfix)

Would like a BooleanChoiceField in Forms

Reported by: Terence Collins Owned by: nobody
Component: Forms Version: 3.1
Severity: Normal Keywords: boolean widget radioselect radio BooleanField ChoiceField forms
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 Terence Collins)

I am using a ChoiceField with a RadioSelect to provide an input to a boolean field, however, the value in forms.cleaned_data comes through as a string. I understand why a choice field would result in a string, however if I place booleans in my values I'd expect them to pass simple equality tests against booleans in the model. Other users implementing this model will likely come up against a bug where False ≠ 'False'. So I'd request a widget (BooleanChoiceField) to cover this case: often a simple checkbox will not provide sufficient interface guidance to a user on the implications of their true/false options.

#in forms.py
class TimingForm(forms.ModelForm):

    TIMING_LEVEL_CHOICES = ( (False, "Time Whole Lines (recommended)"),
                              (True, "Time Individual Words"), )

    word_level_timing = forms.ChoiceField(label='Timing Level', required=True, widget=forms.RadioSelect, choices=TIMING_LEVEL_CHOICES, initial=False)
    class Meta:
        model = TimingThingie
        fields = ['word_level_timing']

#in models.py
class TimingThingie(models.Model):
    word_level_timing = models.BooleanField(default=False)

#in views.py:
def modify_timing(request, tinstance_id):
    tinstance = TimingThingie.objects.get(id=tinstance_id)
    if tinstance.word_level_timing != form.cleaned_data["word_level_timing"]:
        #one is False, the other is 'False', inequality is true against intent and likely introduces a bug  
        pass 
    if tinstance.word_level_timing != bool(strtobool(form.cleaned_data["word_level_timing"])):
        #this works correctly, but is ugly and born only through suffering
        pass

Change History (2)

comment:1 by Terence Collins, 4 years ago

Description: modified (diff)

comment:2 by Mariusz Felisiak, 4 years ago

Resolution: wontfix
Status: newclosed

You should use a BooleanField with a different widget not a ChoiceField, if you want to get data as booleans, e.g.

word_level_timing = forms.BooleanField(widget=forms.RadioSelect(choices=TIMING_LEVEL_CHOICES))

I don't see a reason to add a new field to Django.

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