69👍
You could do this by overriding the field definition in the 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
96👍
Django 1.2 has added the “widgets” Meta option for modelforms:
In your models.py, specify the “choices” for your boolean field:
BOOL_CHOICES = ((True, 'Yes'), (False, 'No'))
class MyModel(models.Model):
yes_or_no = models.BooleanField(choices=BOOL_CHOICES)
Then, in your forms.py, specify the RadioSelect widget for that field:
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'yes_or_no': forms.RadioSelect
}
I’ve tested this with a SQLite db, which also stores booleans as 1/0 values, and it seems to work fine without a custom coerce function.
- [Django]-Django Model MultipleChoice
- [Django]-Can I have a Django model that has a foreign key reference to itself?
- [Django]-Where to put business logic in django
30👍
Modifying Daniel Roseman’s answer a bit, you could fix the bool(“False”) = True problem succinctly by just 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
- [Django]-Referencing multiple submit buttons in django
- [Django]-Feedback on using Google App Engine?
- [Django]-Filter by property
21👍
Here’s the simplest approach I could find (I’m using Django 1.5):
class MyModelForm(forms.ModelForm):
yes_no = forms.BooleanField(widget=RadioSelect(choices=[(True, 'Yes'),
(False, 'No')]))
- [Django]-Using Python's os.path, how do I go up one directory?
- [Django]-Any way to make {% extends '…' %} conditional? – Django
- [Django]-How do I use pagination with Django class based generic ListViews?
13👍
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.')
])}
- [Django]-Django database query: How to get object by id?
- [Django]-Add class to form field Django ModelForm
- [Django]-How to hide some fields in django-admin?
6👍
Same as @eternicode’s answer, but without modifying 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+
- [Django]-Django: sqlite for dev, mysql for prod?
- [Django]-'EntryPoints' object has no attribute 'get' – Digital ocean
- [Django]-Django urls without a trailing slash do not redirect
5👍
Here’s a quick & dirty coerce function using lambda, that gets around the “False” -> True problem:
...
boolfield = forms.TypedChoiceField(coerce=lambda x: x and (x.lower() != 'false'),
...
- [Django]-How can I upgrade specific packages using pip and a requirements file?
- [Django]-How to pass information using an HTTP redirect (in Django)
- [Django]-Django most efficient way to count same field values in a query
5👍
As there is problem in @Daniel Roseman answer, bool(‘False’) –> True, so now i have combined 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 this will work 🙂
- [Django]-Django form: what is the best way to modify posted data before validating?
- [Django]-Form with CheckboxSelectMultiple doesn't validate
- [Django]-Update to Django 1.8 – AttributeError: django.test.TestCase has no attribute 'cls_atomics'
3👍
Also remember that MySQL uses tinyint for Boolean, so True/False are actually 1/0. I used this coerce 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
- [Django]-DateTimeField doesn't show in admin system
- [Django]-How to access the user profile in a Django template?
- [Django]-Django Queryset with year(date) = '2010'
3👍
An other 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)
- [Django]-How to update an existing Conda environment with a .yml file
- [Django]-Django test RequestFactory vs Client
- [Django]-Django get the static files URL in view
2👍
update for django version 3.0:
BOOLEAN_CHOICES = (('1', 'True label'), ('0', 'False label'))
# Filtering fields
True_or_false_question = forms.ChoiceField(
label="Some Label3",
# uses items in BOOLEAN_CHOICES
choices = BOOLEAN_CHOICES,
widget = forms.RadioSelect
)
it gives a bullet point button list, i dont know how to make it not do that
- [Django]-In django, how do I sort a model on a field and then get the last item?
- [Django]-Pulling data to the template from an external database with django
- [Django]-Embedding JSON objects in script tags