代码之家  ›  专栏  ›  技术社区  ›  dar

Django BooleanField作为单选按钮?

  •  63
  • dar  · 技术社区  · 17 年前

    models.BooleanField

    11 回复  |  直到 16 年前
        1
  •  92
  •   eternicode    15 年前

    在models.py中,为布尔字段指定“choices”:

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

    然后,在forms.py中,为该字段指定RadioSelect小部件:

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

    我用SQLite数据库测试了这一点,该数据库还将布尔值存储为1/0值,在没有自定义强制函数的情况下,它似乎工作得很好。

        2
  •  66
  •   mattbasta    13 年前

    您可以通过覆盖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
    
        3
  •  30
  •   Deniz Dogan    15 年前

    稍微修改一下Daniel Roseman的答案,你可以通过使用int来简洁地解决bool(“False”)=True问题:

    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
    
        4
  •  18
  •   Racing Tadpole    11 年前

    class MyModelForm(forms.ModelForm):
        yes_no = forms.BooleanField(widget=RadioSelect(choices=[(True, 'Yes'), 
                                                                (False, 'No')]))
    
        5
  •  12
  •   Kevin White    11 年前

    class EmailSettingsForm(ModelForm):
    
        class Meta:
            model = EmailSetting
            fields = ['setting']
            widgets = {'setting': RadioSelect(choices=[
                (True, 'Keep updated with emails.'),
                (False, 'No, don\'t email me.')             
            ])}
    
        6
  •  6
  •   yprez aet    14 年前

    与@eternicode的答案相同,但不修改模型:

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

    我认为这只适用于Django 1.2+

        7
  •  5
  •   af__    16 年前

    这是一个快速和;使用lambda的脏强制函数,绕过“False”->真正的问题:

    ...
    boolfield = forms.TypedChoiceField(coerce=lambda x: x and (x.lower() != 'false'),
    ...
    
        8
  •  4
  •   Ahsan mtt2p    14 年前

    由于@Daniel Roseman的回答中存在问题,bool('False')-->没错,所以现在我把两个答案结合在一起,得出一个解决方案。

    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
    

        9
  •  3
  •   Denilson Sá Maia    17 年前

    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
    
        10
  •  3
  •   matinfo    13 年前

    另一种解决方案:

    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)
    
        11
  •  2
  •   anthony pizarro    5 年前

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

    它给出了一个要点按钮列表,我不知道如何让它不这样做