10

レポートの生成に使用されるクエリを制御するフィールド (開始日、終了日など) に Django フォーム (新しいフォーム) を使用する Web レポートがあります。私が抱えている問題は、フォームの初期値 (バインドされていない) を使用してページが機能するはずですが、を呼び出さない限り、cleaned_data フィールドにアクセスできないことis_valid()です。ただしis_valid()、バインドされていないフォームでは常に失敗します。

Django のフォームは、バインドされていないフォームが HTML を表示する以外には役に立たないように、データを編集するユースケースで設計されているようです。

たとえば、私が持っている場合:

if request.method == 'GET':
    form = MyForm()
else:
    form = MyForm(request.method.POST)

if form.is_valid():
    do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])

これが GET の場合 (バインドされていないため)、 is_valid() は失敗します。

if request.method == 'GET':
    form = MyForm()
    do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])
else:
    form = MyForm(request.method.POST)
    if form.is_valid():
       do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])

do_query への最初の呼び出しは、まだ呼び出されていないため有効なフィールドではない form.cleaned_data で例外をトリガーしますis_valid()。次のようなことをしなければならないようです:

if request.method == 'GET':
    form = MyForm()
    do_query(form['start_date'].field.initial, form['end_date'].field.initial)
else:
    form = MyForm(request.method.POST)
    if form.is_valid():
       do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])

つまり、バインドされたフォームとバインドされていないフォームの間でフォームの値を取得するための共通のインターフェイスはありません。

これを行うためのよりクリーンな方法を見ている人はいますか?

4

3 に答える 3

7

このメソッドをフォーム クラスに追加すると、次のようになります。

def get_cleaned_or_initial(self, fieldname):
        if hasattr(self, 'cleaned_data'):
            return self.cleaned_data.get(fieldname)
        else:
            return self[fieldname].field.initial

次に、コードを次のように書き直すことができます。

if request.method == 'GET':
    form = MyForm()
else:
    form = MyForm(request.method.POST)
    form.is_valid()

do_query(form.get_cleaned_or_initial('start_date'), form.get_cleaned_or_initial('end_date'))
于 2008-09-16T19:18:57.910 に答える
2

Unbound means there is no data associated with form (either initial or provided later), so the validation may fail. As mentioned in other answers (and in your own conclusion), you have to provide initial values and check for both bound data and initial values.

The use case for forms is form processing and validation, so you must have some data to validate before you accessing cleaned_data.

于 2008-09-17T09:02:07.463 に答える
0

初期値の辞書をフォームに渡すことができます:

if request.method == "GET":
    # calculate my_start_date and my_end_date here...
    form = MyForm( { 'start_date': my_start_date, 'end_date': my_end_date} )
...

公式のフォーム API ドキュメントを参照してください。

編集:他のユーザーからの回答に基づいて、おそらくこれが最もクリーンなソリューションです:

if request.method == "GET":
    form = MyForm()
    form['start_date'] = form['start_date'].field.initial
    form['end_date'] = form['end_date'].field.initial
else:
    form = MyForm(request.method.POST)
if form.is_valid():
    do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])

私はこれを試していません。誰かがこれが機能することを確認できますか? これは、新しいメソッドを作成するよりも優れていると思います。このアプローチでは、新しい「魔法の」アクセサーを知るために他のコード (おそらくあなたが作成したものではない) を必要としないためです。

于 2008-09-16T19:07:39.513 に答える