【问题标题】:Django: Display NullBooleanField as Radio and default to NoneDjango:将 NullBooleanField 显示为 Radio,默认为 None
【发布时间】:2012-08-13 00:29:13
【问题描述】:

我以多种方式成功地将NullBooleanField 实现为单选按钮,但问题是我无法将默认值设置为无。

这是代码:

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 

我尝试了以下方法: 在模型中设置default:None 和/或在表单中设置inital:None 以及在表单实例的视图中。
这些都没有成功。我目前使用CharField 而不是NullBooleanField。
但是有什么方法可以通过NullBooleanField获得这个结果???

【问题讨论】:

    标签: python django forms form-fields


    【解决方案1】:

    我已经使用 Django 2.2 实现了这一点。

    您应该能够使用ChoiceField 和RadioSelect 小部件检查None 单选选项。诀窍是将None 选择值设置为空字符串''。

    我使用的模型字段是BooleanField 和null=True,这与模型字段NullBooleanField 基本相同。

    approved = forms.ChoiceField(
        choices=[(True, 'Yes'), (False, 'No'), ('', 'N/A')],
        widget=forms.RadioSelect,
        required=False,
    )
    

    【讨论】:

      【解决方案2】:

      对于 Django 1.7 中的我来说,默认情况下不选择 None 值(尽管 Craig 声称)。我对 RadioSelect 进行了子类化,它对我的​​情况有所帮助:

      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
      

      【讨论】:

        【解决方案3】:

        不管怎样,这里给出的其他答案不再适用于 Django 1.7。将choices 设置为[(True, "Yes"), (False, "No"), (None, "N/A")] 就可以了。

        【讨论】:

        【解决方案4】:

        出于某种奇怪的原因 - 我没有在 Django 代码中检查它 - 一旦您为 NullBooleanField 提供自定义小部件,它就不会接受您期望的值(None、True 或False) 了。

        通过分析内置的choices属性,我发现这些值分别等于1、2和3。

        所以,这是我犯规的快速而肮脏的解决方案,坚持使用默认为“未知”的单选按钮:

        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'
        

        它看起来不太好,除非非常必要,否则我不会使用它。但它就在那里,以防万一。

        【讨论】:

          【解决方案5】:

          我知道这个问题已经得到了一段时间的回答,但我也在尝试解决这个问题并遇到了这个问题。

          在尝试了 emyler 的解决方案后,它似乎有效,但是当我查看表单的 self.cleaned_data 时,我看到我返回的值都是 True 或 None,没有记录 False 值.

          我查看了 Django 代码,发现虽然正常的 NullBooleanField 选择确实将 None、True、False 映射到 1、2、3,但 RadioSelect 映射 @987654331 @ 到 True、0 到 False 以及任何其他值到 None

          这是我最终使用的:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-03-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-06-01
            相关资源
            最近更新 更多