4

フラスコ アプリの 1 ページに 2 つのフォームを配置する予定です。1 つは一般的なユーザー情報を編集するためのもので、もう 1 つはパスワードをリセットするためのものです。テンプレートはこんな感じ

{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block page_content %}                                                   
<div class="page-header">                                                  
    <h1>Edit Profile</h1>
</div>

{{ wtf.quick_form(form_profile, form_type='horizontal') }}                 

<hr>

{{ wtf.quick_form(form_reset, form_type='horizontal') }}                   

<hr>
{% endblock %} 

各フォームには送信ボタンがあります。

ルート関数では、このように2つのフォームを分離しようとしました

form_profile = ProfileForm()
form_reset = ResetForm()

if form_profile.validate_on_submit() and form_profile.submit.data:
    ....
if form_reset.validate_on_submit() and form_reset.submit.data:
    .....

しかし、うまくいきませんでした。ResetForm のボタンをクリックすると、ProfileForm 検証ロジックが実行されます。

問題は、wtf.quick_form()2 つの同一の送信ボタンが作成されることだと思いますが、よくわかりません。

この場合、どうすればよいですか?bootstrap/wtf.htmlテンプレートはこの状況に対処できますか?

4

1 に答える 1

14

次のように、この 2 つの SubmitField を異なる名前で定義します。

class Form1(Form):
    name = StringField('name')
    submit1 = SubmitField('submit')

class Form2(Form):
    name = StringField('name')
    submit2 = SubmitField('submit')

次にview.py

....
form1 = Form1()
form2 = Form2()

if form1.submit1.data and form1.validate_on_submit():  # notice the order 
....
if form2.submit2.data and form2.validate_on_submit():  # notice the order 
....

これで問題は解決しました。

それに飛び込みたい場合は、読み続けてください。

ここにあるvalidate_on_submit()

    def validate_on_submit(self):
        """
        Checks if form has been submitted and if so runs validate. This is
        a shortcut, equivalent to ``form.is_submitted() and form.validate()``
        """
        return self.is_submitted() and self.validate()

そしてここにあるis_submitted()

    def is_submitted(self):
        """
        Checks if form has been submitted. The default case is if the HTTP
        method is **PUT** or **POST**.
        """

        return request and request.method in ("PUT", "POST")

を呼び出すとform.validate_on_submit()、どの送信ボタンがクリックされても、HTTP メソッドによってフォームが送信されたかどうかがチェックされます。したがって、上記の小さなトリックは、フィルタを追加するだけです (送信にデータがあるかどうかを確認するため、つまりform1.submit1.data)。

さらに、if の順序を変更するため、1 つの送信をクリックすると、このフォームに対してのみ validate() が呼び出され、両方のフォームの検証エラーが防止されます。

物語はまだ終わっていません。ここにある.data

@property
def data(self):
    return dict((name, f.data) for name, f in iteritems(self._fields))

フィールド名 (キー) とフィールド データ (値) を含む dict を返しますが、2 つのフォーム送信ボタンは同じ名前submit(キー) を持っています!

最初の送信ボタン (form1 内) をクリックすると、からの呼び出しはform1.submit1.data次のような dict を返します。

temp = {'submit': True}

を呼び出すと、間違いなくif form1.submit.data:返されTrueます。

2 番目の送信ボタン (form2 内) をクリックすると、最初に dict にキー値を追加する.dataための呼び出しが行われ、次に別のキー値を追加するための呼び出しが行われます。最終的に、dict は次のようになります。if form1.submit.data:if form2.submit.data:

temp = {'submit': False, 'submit': True}

ここで を呼び出すと、クリックした送信ボタンが form2 にあったとしても がif form1.submit.data:返されます。True

SubmitFieldそのため、この 2 つを異なる名前で定義する必要があります。ところで、(ここまで)読んでくれてありがとう!

nos の通知に感謝します。彼は について問題を追加しましたvalidate()。以下のコメントを確認してください。

于 2016-09-28T06:43:55.963 に答える