2009-05-12 35 views

答えて

58

あなたはの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 
+7

残念ながら、これは動作しませんでしたが、強制ためには= boolはブール値ではなく、bool( "False")=> Trueではなく文字列値が渡されています。だから私は文字列の値を取ってboolに変換するカスタムコルカス関数を書かなければなりませんでした。ポインタありがとう。 – dar

+1

@ darのように、これは 'bool( 'False')' => 'True'から実際にはうまくいきませんので、実際に更新する必要があります。 –

+0

@Daniel、bool( 'False')はTrueを返します。 –

3

また偽/そうTrueの場合、MySQLはブールのためのtinyint型を使用していることを覚えて実際に1/0です。私は、この強制機能を使用:

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 
30

修正ダニエルローズマンの答えビットを、あなたは(「偽」)ブール値を修正する可能性だけではなく、int型を使用して簡潔に真の問題を=:

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 
+2

これは私の編集フォームでは機能しません。フィールドの現在の値はモデルから引き出されません。代わりにエターナルコードの答えを使用しました。 – Dave

5

ここでは簡単です&「偽」の周りを取得ラムダを使用して、汚れた強制機能 - >真の問題:01:

... 
boolfield = forms.TypedChoiceField(coerce=lambda x: x and (x.lower() != 'false'), 
... 
82

ジャンゴ1.2はmodelformsのための「ウィジェット」のMetaオプションを追加しましたあなたのmodels.pyで 、あなたのブールフィールドの "選択項目" を指定します。

​​

BOOL_CHOICES = ((True, 'Yes'), (False, 'No')) 

class MyModel(models.Model): 
    yes_or_no = models.BooleanField(choices=BOOL_CHOICES) 

次に、あなたのforms.pyで、そのフィールドのRadioSelectウィジェットを指定します私はSQLite dbでこれをテストしました。これはブール値を1/0の値として格納しています。カスタムコルカス関数を使用しなくてもうまくいくようです。

+4

最もクリーンで、ほとんどの "Django"の解決策です。ありがとう! –

+0

これは素晴らしいことです。 'django.utils.translation import ugettext_lazy as _'を使用し、' BOOL_CHOICES'を次のように更新することにより、 'Yes'と 'No'のローカライズ版を少し修正するでしょう: 'BOOL_CHOICES =((True、_( 'はい'))、(False、_( 'No'))) ' – tatlar

+5

私はそれをローカライズする余分なコードは、ポイントから気を散らすだろうと思います。読者のための練習;) – eternicode

3

@ダニエルローズマンの答えには、bool( 'False') - > Trueという問題があるので、ここでは2つの答えを組み合わせて1つの解決策を作りました。

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 

さて、これは動作します:)

3

eternicodeの答え@と同じですが、モデルを変更せずに:

class MyModelForm(forms.ModelForm): 
    yes_no = forms.RadioSelect(choices=[(True, 'Yes'), (False, 'No')]) 

    class Meta: 
     model = MyModel 
     widgets = {'boolfield': yes_no} 

私はジャンゴ1.2+でのみ動作を考える

3

アン他の解決策:

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

ここで私は(私はDjangoの1.5を使用しています)見つけることができる最も簡単な方法です:次は私のために働いたDjangoの1.6では、

class MyModelForm(forms.ModelForm): 
    yes_no = forms.BooleanField(widget=RadioSelect(choices=[(True, 'Yes'), 
                  (False, 'No')])) 
+0

これは適切な答えです。 –

+0

このソリューションの検証は機能しますが、[文書の注記](https://docs.djangoproject.com/en/1.10/ref/forms/fields/#booleanfield)を参照してください。フィールドにrequired = Falseを設定する必要があります。 – grokpot

9

class EmailSettingsForm(ModelForm): 

    class Meta: 
     model = EmailSetting 
     fields = ['setting'] 
     widgets = {'setting': RadioSelect(choices=[ 
      (True, 'Keep updated with emails.'), 
      (False, 'No, don\'t email me.')    
     ])} 
関連する問題