2016-11-26 1 views
2

私のFlaskアプリでは、wtformsjinjaテンプレートで生成されたフォームがあります。バリデーションが合格すれば新しいタブにリダイレクトしたい、そうでなければ同じページにいてエラーを表示したいしかし、自分のフォームにtarget="_blank"を設定すると、バリデーションを渡さずに新しいタブが開き、そこでエラーが表示されます。 target="_blank"を削除しても、新しいタブは開きません。 jsの検証全体を書き直すことなくこれを達成する方法はありますか?ありがとう!Flask app submit target = "_ blank"フォームは、妥当性検査の後にのみ有効です。

コード:

from wtforms import Form, TextAreaField, StringField, validators 

class SubmitForm(Form): 
    field1 = StringField(u'field1', [validators.DataRequired()]) 
    field2 = TextAreaField(u'field2', [validators.DataRequired()]) 

@app.route('/', methods=['POST']) 
def sub(): 
    form = SubmitForm(request.form) 
    if request.method == 'POST' and form.validate(): 
     # great success 
     return redirect('/my_redirect_uri') 
    return render_template('index.html', form=form) 

@app.route('/') 
def layout(): 
    return render_template('index.html', form=SubmitForm()) 

のindex.html:

{% from "_formhelpers.html" import render_field %} 
<form method=post action="/" target="_blank"> 
    <dl> 
    {{ render_field(form.field1) }} 
    {{ render_field(form.field2) }} 
    </dl> 
    <p><input type=submit value=Submit> 
</form> 

_formhelpers.html(つまり、関連するが、completnessのためにではない):

{% macro render_field(field) %} 
    <dt>{{ field.label }} 
    <dd>{{ field(**kwargs)|safe }} 
    {% if field.errors %} 
    <ul class=errors> 
    {% for error in field.errors %} 
     <li>{{ error }}</li> 
    {% endfor %} 
    </ul> 
    {% endif %} 
    </dd> 
{% endmacro %} 
+0

私はあなたが正しいと思います。 Ajaxリクエストを検証するシンプルなコントローラを作成する必要があります。その後、新しいタブを開くことができます。 –

答えて

2

主な問題

formオブジェクトと、フォームフィールドを表す変数、つまりfield1field2を渡す必要があります。

詳細何前述されていることは、あなたが変更する必要があることを意味

return redirect('/my_redirect_uri', form=form, field1=field1, field2=field2)

return redirect('/my_redirect_uri')

これはまた、あなたを調整しなければならないことを意味します表示方法:

以下の原則

  • コード:
    @app.route('/', methods=['POST']) 
    def sub(): 
        form = SubmitForm(request.form) 
        if request.method == 'POST' and form.validate(): 
         # great success 
         field1 = form.field1.data 
         field2 = form.field2.data 
         return redirect('/my_redirect_uri', form=form, field1=field1, field2=field2) 
        return render_template('index.html', form=form) 
    

    は今、あなたのプログラムにいくつかの改善がある

if form.validate_on_submit():によってif request.method == 'POST' and form.validate():

  • 使用url_for()を(あなたは一つの命令を保存)に置き換え:

scalabilityのために、プログラムの将来のバージョンおよび再編集では、URLマップを使用してURLを生成するときにurl_for()を使用すると、ルート名に対する変更が自動的に利用可能になるためです。

セッションは、フォームデータが送信されているアプリケーション「覚えておくこと」になります:あなたは

  • 使用セッション(あなたは私が詳細については提供されたリンクをチェックすること)return redirect('/my_redirect_uri')でそれを使用することができます。あなたの例では、セッションをこのように使用することができます。

    session['field1'] = form.field1.data 
    session['field2'] = form.field2.data 
    

    これは、例えば、上記の行を意味しますことを

    return redirect('my_redirect_uri', form=form, session.get('field1'), session.get('field2')) 
    

    注:

    return redirect('/my_redirect_uri', form=form, field1=field1, field2=field2) 
    

    に変更する必要がありますセッションを実装したい場合は、秘密鍵がクライアント側に格納されているため、秘密鍵を設定する必要があります。そのため、(Phaskの考え方では暗号的に)保護する必要があります。これは、アプリケーションを次のように設定する必要があることを意味します。

    実際には、開いたブラウザのタブには問題はありません。全体の問題は、redirect()ステートメントから出ています。

    なぜセッションを使用するのが良いかについての詳細は?リダイレクトについて

    言葉::次の最後のセクションを確認してください

    あなたのPOSTリクエストがredirectによって処理され、フォームデータに、その結​​果、あなた緩いアクセスをPOSTリクエストが終了したとき。

    リダイレクトステートメントは、受信したときにブラウザがGET要求を発行する単なる応答です。このメカニズムは、主に次のような状況に対応しています。

    フォームデータを送信したときと同じブラウザウィンドウをリフレッシュしようとすると、ブラウザにはポップアップウィンドウが表示され、ブラウザは、最後に実行した要求をブラウザが覚えているため、データを再度送信します。もちろん、これはあなたのアプリケーションのユーザーにとっては厄介です。セッションが必要です。これは、リダイレクト先のブラウザタブにも役立ちます。

関連する問題