2011-12-17 12 views
40

を確認しない限り、私は次の形式を使用するアプリケーションがあります。私の見解では以下を使用します。Djangoのフォーム常に無効

<form class="confirmform" action="/foo/" enctype="multipart/form-data" method="post"> 
{{ confirm_form.up_to_date }} Check if this data brings the account up to date.<br> 
{{ confirm_form.account_name }} <input type="submit" name="confirm" value="Confirm" /> 
</form> 

class ConfirmForm(forms.Form): 
    account_name = forms.CharField(widget=forms.HiddenInput) 
    up_to_date = forms.BooleanField(initial=True) 

私は次のテンプレート抜粋でフォームを使用します基本的なコード構造:

if request.method == 'POST': 
    #check for 'confirm' because I actually have multiple forms in this page 
    if 'confirm' in request.POST: 
     confirm_form = ConfirmForm(request.POST) 
     if confirm_form.is_valid(): 
      #do stuff 
     else: 
      c['confirm_form'] = confirm_form 
else: 
    c['confirm_form'] = ConfirmForm({'account_name':'provided_value'}) 

2つのことが間違っている:

1)私がTrue =初期持っているにもかかわらず、ページのロード

2、チェックボックスがオフになっている)私は、チェックボックスをチェックしない限り、フォームは常に無効です。 up_to_dateにのみエラーが表示されます: "このフィールドは必須です。"

私はthis similar questionを読んでいますが、彼の解決策は私のプロジェクトには当てはまりません。

だから...何が起こっているのですか?

編集:私は私の実際のコードに、より忠実であるために、上記のコードを更新

問題#1は、フォームがインスタンス化されたときにデータをバインドして初期値を上書きしていたため、私のせいでした。

問題#2問題はまだ考えられます。 up_to_daterequired=Falseを使用すると問題は解決しますが、BooleanFieldNULL(妥当性チェックが失敗する)またはTrueのいずれかになりますが、Falseにはなりません。

答えて

32

は、ウィジェットをchecked="checked"でレンダリングする必要があります。問題はありません。しかし、フォームが無効な理由は、特に指定しない限り、すべてのフィールドがデフォルトで必要なためです。デフォルトでは

Field.required¶は、各フィールドのクラスは、値が が必要とされていると仮定するので、あなたは空の値を渡した場合 - Noneまたは空の の文字列(「」)のどちらか - (その後、クリーンを)ValidationErrorを発生させます例外:

チェックボックスなどの任意の値をオプションにする場合は、required=Falseをフォームフィールドコンストラクタに渡す必要があります。

up_to_date = forms.BooleanField(initial=True, required=False) 
# no longer required.. 
+5

なしless、initial = Trueは効果がありません。また、なぜ解決策はフィールドをオプションにすることでしょうか? BooleanFieldがfalseを返すことはできませんか? – dhowland

+0

HTMLは "checked"で表示されますか?サーバーを再起動しましたか?その時点でデバッガ( 'import pdb; pdb.set_trace()')を起動して、初​​期属性が正しく設定されていることを再確認できますか? 'assert form.fields ['up_to_date']。初期== True'これらは、問題を絞ってくれるでしょう。 –

+1

なぜフィールドをオプションにしますか? 1:ドキュメントはそう言います。しかし、2:チェックボックスは、チェックされていないときにデータを送信しないHTML要素です。 'False'値は、入力の欠如によってのみ決定できます。 –

0

最初にページが読み込まれたときに上書きしないようにしてください。

私はもともと要求があったかどうかを確認していませんでした。最初にページがrequest.GETをロードするとNoneとなり、SomeForm(request.GET)を呼び出すと実際に初期値が消去されます。

def some_view(request): 

    form = SomeForm() 

    if request.method == 'GET': 
     form = SomeForm(request.GET) 

リクエストに何かがあることを確認するためにチェックを追加してください。これを修正しました。

24

Djangoフォームでは、ブールフィールドをrequired=Falseで作成する必要があります。

このチェックボックスをオフにすると、ブラウザーはリクエストのPOSTパラメーターでフィールドを送信しません。フィールドがオプションであることを指定しなければ、DjangoはPOSTパラメータにないときにフィールドを欠落として扱います。私見

Djangoはブールフォームフィールドのため、デフォルトでこの動作を持っているため、それはいいだろう。..

(これはすでに雄二のコメントに答えたが、それは答えとして有用であろう)

+6

それは私に悪いデザインのようなにおいをしません... –

8

よります

あなたがTrueまたはFalseのいずれかになりますフォームのboolean(例えばオンまたはオフのチェックボックス)を含めたい場合は、あなたがに渡すために覚えておく必要があります。official docsへBooleanFieldを作成するときは、です。