Django: Display NullBooleanField as Radio and default to None

血红的双手。 提交于 2020-01-01 15:48:28

问题


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???


回答1:


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.




回答2:


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'
)



回答3:


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.




回答4:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!