Django BooleanField how are the switches?

Is there a widget in Django 1.0.2 to render models.BooleanField as two radio buttons instead of a checkbox?

+50
django django-models django-forms
May 12, '09 at 20:21
source share
10 answers

You can do this by overriding the field definition in ModelForm:

 class MyModelForm(forms.ModelForm): boolfield = forms.TypedChoiceField( coerce=lambda x: x == 'True', choices=((False, 'False'), (True, 'True')), widget=forms.RadioSelect ) class Meta: model = MyModel 
+57
May 12 '09 at 20:42
source share

Django 1.2 added a widget option for models:

In your models.py, specify a "choice" for your boolean field:

 BOOL_CHOICES = ((True, 'Yes'), (False, 'No')) class MyModel(models.Model): yes_or_no = models.BooleanField(choices=BOOL_CHOICES) 

Then, in the forms.py file, specify the RadioSelect widget for this field:

 class MyModelForm(forms.ModelForm): class Meta: model = MyModel widgets = { 'yes_or_no': forms.RadioSelect } 

I tested this with SQLite db, which also stores booleans as 1/0 values, and it seems to work fine without using a special coercion function.

+81
Oct 18 2018-10-18
source share

By changing Daniel Roseman a bit, you can fix the error bool ("False") = True by simply using ints instead:

 class MyModelForm(forms.ModelForm): boolfield = forms.TypedChoiceField(coerce=lambda x: bool(int(x)), choices=((0, 'False'), (1, 'True')), widget=forms.RadioSelect ) class Meta: model = MyModel 
+30
Sep 10 '09 at 15:31
source share

In Django 1.6, the following worked for me:

 class EmailSettingsForm(ModelForm): class Meta: model = EmailSetting fields = ['setting'] widgets = {'setting': RadioSelect(choices=[ (True, 'Keep updated with emails.'), (False, 'No, don\'t email me.') ])} 
+8
Aug 19 '14 at 13:27
source share

Here's a quick and dirty use function using lambda that bypasses the "False" -> True problem:

 ... boolfield = forms.TypedChoiceField(coerce=lambda x: x and (x.lower() != 'false'), ... 
+5
May 26 '10 at 21:55
source share

Here is the easiest approach I could find (I am using Django 1.5):

 class MyModelForm(forms.ModelForm): yes_no = forms.BooleanField(widget=RadioSelect(choices=[(True, 'Yes'), (False, 'No')])) 
+5
Jul 02 '14 at 5:12
source share

Also remember that MySQL uses tinyint for Boolean, so True / False is actually 1/0. I used this coercion function:

 def boolean_coerce(value): # value is received as a unicode string if str(value).lower() in ( '1', 'true' ): return True elif str(value).lower() in ( '0', 'false' ): return False return None 
+3
Jun 18 '09 at 8:35
source share

As there is a problem in @Daniel Roseman, bool ('False') β†’ True, so now I have combined the two answers here to make one solution.

 def boolean_coerce(value): # value is received as a unicode string if str(value).lower() in ( '1', 'true' ): return True elif str(value).lower() in ( '0', 'false' ): return False return None class MyModelForm(forms.ModelForm): boolfield = forms.TypedChoiceField(coerce= boolean_coerce, choices=((False, 'False'), (True, 'True')), widget=forms.RadioSelect ) class Meta: model = MyModel 

Now it will work :)

+3
Jul 20 2018-11-11T00:
source share

Same as @eternicode's answer, but without changing the model:

 class MyModelForm(forms.ModelForm): yes_no = forms.RadioSelect(choices=[(True, 'Yes'), (False, 'No')]) class Meta: model = MyModel widgets = {'boolfield': yes_no} 

I think this only works in Django 1.2+

+3
Jan 12 2018-12-12T00:
source share

Another solution:

 from django import forms from django.utils.translation import ugettext_lazy as _ def RadioBoolean(*args, **kwargs): kwargs.update({ 'widget': forms.RadioSelect, 'choices': [ ('1', _('yes')), ('0', _('no')), ], 'coerce': lambda x: bool(int(x)) if x.isdigit() else False, }) return forms.TypedChoiceField(*args, **kwargs) 
+3
Mar 05 '13 at 13:12
source share



All Articles