I am successfully implementing NullBooleanField
as radio buttons in several ways but the problem is that I can not set the default value to None.
Here is the code:
models.py:
class ClinicalData(models.Model):
approved = models.NullBooleanField()
...
forms.py:
NA_YES_NO = ((None, 'N/A'), (True, 'Yes'), (False, 'No'))
class ClinicalDataForm(ModelForm):
approved = forms.BooleanField(widget=forms.RadioSelect(choices=NA_YES_NO))
class Meta:
model = ClinicalData
I tried the following methods:
Set default:None
in the model and/or setting inital:None
in the form and also in the view in the form instance.
None of that was successfull. Im currently using CharField
instead of NullBooleanField
.
But is there some way to get this results with NullBooleanField
???
For some odd reason - I didn't check it at the Django code -, as soon as you provide a custom widget for a NullBooleanField, it doesn't accept the values you expect (None
, True
or False
) anymore.
By analyzing the built-in choices attribute, I found out that those values are equal to, respectively, 1
, 2
and 3
.
So, this is the quick-and-dirty solution I fould to stick to radio buttons with 'Unknown' as default:
class ClinicalDataForm(forms.ModelForm):
class Meta:
model = ClinicalData
def __init__(self, *args, **kwargs):
super(ClinicalDataForm, self).__init__(*args, **kwargs)
approved = self.fields['approved']
approved.widget = forms.RadioSelect(
choices=approved.widget.choices)
approved.initial = '1'
It doesn't look good and I wouldn't use it unless very necessary. But there it is, just in case.
I know this has been answered for a while now, but I was also trying to solve this problem and came across this question.
After trying emyller's solution, it seemed to work, however when I looked at the form's self.cleaned_data
, I saw that the values I got back were all either True
or None
, no False
values were recorded.
I looked into the Django code and saw that while the normal NullBooleanField select does indeed map None
, True
, False
to 1
, 2
, 3
respectively, the RadioSelect maps 1
to True
, 0
to False
and any other value to None
This is what I ended up using:
my_radio_select = forms.NullBooleanField(
required=False,
widget=widgets.RadioSelect(choices=[(1, 'Yes'), (0, 'No'), (2, 'N/A')]),
initial=2, # Set initial to 'N/A'
)
For what it's worth, the other answers given here no longer apply in Django 1.7. Setting choices
to [(True, "Yes"), (False, "No"), (None, "N/A")]
works just fine.
For me in Django 1.7 None value is not selected by default (despite what Craig claims). I subclassed RadioSelect, it helped in my case:
from django.forms.widgets import RadioSelect
from django.utils.translation import ugettext_lazy
class NullBooleanRadioSelect(RadioSelect):
def __init__(self, *args, **kwargs):
choices = (
(None, ugettext_lazy('Unknown')),
(True, ugettext_lazy('Yes')),
(False, ugettext_lazy('No'))
)
super(NullBooleanRadioSelect, self).__init__(choices=choices, *args, **kwargs)
_empty_value = None
来源:https://stackoverflow.com/questions/11990852/django-display-nullbooleanfield-as-radio-and-default-to-none