まず、pythonとFlaskに慣れていないので、質問がばかげている場合は申し訳ありません。検索しましたが、答えが見つかりませんでした(これは「簡単な」質問だと思います) )。
私は自分のウェブサイトに連絡先ページを追加したかったのですが、 このチュートリアル を見つけたので、それに従いました。フォームの検証まで、すべてが正常に機能しました。私はRequiredのみを使用し、form.validate()は常にfalseを返しました。コードに触れず、フォームクラスのすべてのRequiredを削除すると、正常に機能し、form.validate()はtrueを返します。
理由がよくわかりません。validate_on_submit()を使用する必要があることをよく読んでいますが、使用するとエラーが発生します。 *「ClassName」オブジェクトには属性がありません「validate_on_submit」*
コードの関連部分は次のとおりです。
Index.py
@app.route('/contact', methods=['GET','POST'])
def contact():
form = ContactForm()
if request.method == 'POST':
if form.validate() == False:
flash('All Fields are required.')
return render_template('contact.html', form=form)
else:
return 'Form posted'
Elif request.method == 'GET':
return render_template('contact.html', form=form)
forms.py
from wtforms import Form, TextField, TextAreaField, SubmitField, validators,ValidationError
class ContactForm(Form):
name = TextField("Name", [validators.Required()])
email = TextField("Email")
subject = TextField("Subject")
message = TextAreaField("Message")
submit = SubmitField("Send")
contact.html
<div id="contact">
{% for message in get_flashed_messages() %}
<div class="flash">{{ message }}</div>
{% endfor %}
<form action="{{ url_for('contact') }}" method=post>
{{ form.name.label }}
{{ form.name }}
{{ form.email.label }}
{{ form.email }}
{{ form.subject.label }}
{{ form.subject }}
{{ form.message.label }}
{{ form.message }}
{{ form.submit }}
</form>
</div>
[名前]フィールドに何かを入力しても、「フォームが投稿されました」という文字列が表示されません。
前もって感謝します、
リクエストの値を使用してフォームインスタンスを初期化する必要があります。
from flask import request
@app.route('/contact', methods=['GET','POST'])
def contact():
form = ContactForm(request.form)
if request.method == "POST" and form.validate():
# do something with form
# and probably return a redirect
return render_template("contact.html", form=form)
これは、質問でリンクするチュートリアルよりも優れたチュートリアルです: http://flask.pocoo.org/docs/patterns/wtforms/ 。
チュートリアルのテンプレートレンダリングコードを見て、フォームフィールドエラーをレンダリングしていることを確認してください。フォームが投稿されたが検証されない場合、コードはrender_template
にフォールスルーし、フォームインスタンスにフィールド検証エラーが含まれます(詳細については、チュートリアルとWTFormsのドキュメントを参照してください)。
MiguelGrinbergの著書「FlaskWebDevelopment」のデモコードに従ってログインフォームをテストしているときは、常にform.validate_on_submit()に失敗します。だから私はデバッグする方法を見つけるべきだと思います。
私が採用しているデバッグアプローチは、以下のコードをapp/auth /views.pyに追加することです。
flash(form.errors)
次に、ログインページにアクセスすると、原因が表示されます。
errors={'csrf_token': ['CSRF token missing']}
したがって、form.errorsメッセージを使用してデバッグすることをお勧めします。
問題が発生したばかりで、解決策はテンプレートのフォームのすぐ下にhidden_tag
を追加することでした。
...
<form action="{{ url_for('contact') }}" method=post>
{{ form.hidden_tag() }}
...
@Paul Vergeevとして、次を追加するだけです。
_<form action="{{ url_for('contact') }}" method=post>
{{ form.csrf_token }}
_
フォームにはバリデータが含まれているため、これが必要です。したがって、htmlフォームに「Hidden」タイプの「入力」が追加されます。 HTMLにこの非表示のトークンがないと、バリデーターはユーザーの入力を検証できず、検証の結果は常にFalseになります。
_{{ form.hidden_tag() }}
_
hTMLコードにすべての非表示の入力フィールドが含まれます。ただし、ページには表示されません。
_{{ form.csrf_token }}
_
hTMLコードに非表示のcsrf_token入力フィールドのみが含まれます。ただし、ページには表示されません。
もう1つ行うこと:アプリの_SECRET_KEY
_を構成する必要があります。これを行うには、アプリの初期化のすぐ下、つまりapp = Flask(__name__)
の直後に_app.config["SECRET_KEY"] = "a secret key you won't forget"
_を含めます。
これはすべて、WTFormsバリデーターがサイトをCSRF(c-surfと発音されることが多い)から保護するための方法です。 CSRFの詳細も読むことができます ここ 。