Flask_WTF とは
フォームが簡単に作成できるFlaskの外部ライブラリです。
バリデーション設定や、CSRFセキュリティ対策も、よしなにやってくれる。
この記事では基本的な使い方を説明します。
フォームの見た目は装飾せず、機能のコードに極力留めています。
(色々コードを入れると混乱するため)
基本的な使い方
ターミナル
pip3 install Flask-WTF
事前設定
from flask import Flask, render_template, url_for, redirect, session
from flask_wtf import FlaskForm
from wtforms import ValidationError, StringField, PasswordField, SubmitField
#Flaskアプリをインスタンス化
app = Flask(__name__)
# フォームを利用する際に必要。セキュリティ対策に必要。
app.config['SECRET_KEY'] = 'mysecretkey'
-
-
# この記述がないとアプリを起動できないので、ファイル末尾などに記述を忘れない。
if __name__ == "__main__":
app.run(debug=True)
フォームクラス
"""
継承元のFlaskFormクラスの機能を使えるようになる。
各フィールドを定義する。ここで定義したフィールドを基にHTMLに配置する。
"""
class RegistrationForm(FlaskForm):
email = StringField()
username = StringField()
password = PasswordField()
pass_confirm = PasswordField()
submit = SubmitField()
View関数
"""
"/register" にリクエストが送られると、フォームが作成され、最後のreturn文でユーザー登録ページを表示する。
フォームにデータが入力され、送信されると、再度このビュー関数が呼ばれる。
その際はフォームにデータ入力されているので、入力チェックに問題なければif文の処理の中も実行される
"""
@app.route("/register", methods=["GET", "POST"])
def register():
#フォームを取得
form = RegistrationForm()
#フォームにデータ入力されていれば、入力チェック
if form.validate_on_submit():
#フォーム情報をセッションに格納
session["email"] = form.email.data
session["username"] = form.username.data
session["password"] = form.password.data
#ユーザー管理ページに転送
return redirect(url_for("user_maintenance"))
#フォームにはデータが入力されていない状態だと、if文の中は処理されず、ユーザー登録ページを表示する
return render_template("register.html", form=form)
#ユーザー一覧画面のデコレータ。呼び出されたら画面を表示するだけの設定をしておく。
#ここでは、フォームで送信した内容を受け取れているかチェックするため。
@app.route("/user_maintenance")
def user_maintenance():
return render_template("user_maintenance.html")
テンプレート(HTML)
"templates"という名前でフォルダ作成し、そのフォルダ内にhtmlファイルを入れる必要がある。
今回は、"register.html"という名前でhtmlファイルを作成し、以下の記述でフォーム作成する。
<form method="POST">
<!-- CSRF対策(トークンが生成される) -->
{{ form.hidden_tag() }}
<div>
{{ form.username.label }} {{ form.username() }}
</div>
<div>
{{ form.email.label }} {{ form.email() }}
</div>
<div>
{{ form.password.label }} {{ form.password() }}
</div>
<div>
{{ form.pass_confirm.label }} {{ form.pass_confirm() }}
</div>
{{ form.submit() }}
</form>
フォームからのセッションデータが送られているか確認するために、ユーザー一覧画面を用意。
<h2>ユーザー管理画面</h2>
# 新規登録画面に移動するリンクを生成
<a href="{{ url_for('register' )}}">
ユーザー登録
</a>
<table>
<thead>
<tr>
<th>ユーザー名</th>
<th>メールアドレス</th>
</tr>
</thead>
<tbody>
<tr>
# セッションから名前とメールアドレスを取り出す
<td>{{ session['username'] }}</td>
<td>{{ session['email'] }}</td>
</tr>
</tbody>
</table>
表示確認
app.py でサーバーを立ち上げ、"/register" をパスパラメータに付けてブラウザ表示する。
名前などフォームに入れて、送信。
上記の画面で送信すると、リダイレクト先のユーザー管理画面に遷移する。
新規登録ページで入力した、名前とメールアドレスが表示される。
バリデーション設定を追記
フォームに入力した内容がルールに反していた場合に、エラー表示されるよう、コードを追記
インポート
from flask import Flask, render_template, url_for, redirect, session
from flask_wtf import FlaskForm
from wtforms import ValidationError, StringField, PasswordField, SubmitField
# 以下を追記
from wtforms.validators import DataRequired, Email, EqualTo
フォームクラス
StringField などのカッコ内に、
各フィールドのバリデーションルールを追記。
class RegistrationForm(FlaskForm):
email = StringField('メールアドレス', validators=[DataRequired(), Email(message='正しいメールアドレスを入力してください')])
username = StringField('ユーザー名', validators=[DataRequired()])
password = PasswordField('パスワード', validators=[DataRequired(), EqualTo("pass_confirm", message='パスワードが一致していません')])
pass_confirm = PasswordField('パスワード(確認)', validators=[DataRequired()])
submit = SubmitField('登録')
- 全て必須入力
- password と pass_confirmは一致が必須
- ラベル名を日本語に設定
- エラーメッセージを日本語に設定
テンプレート
エラーメッセージが表示されるように追記。
<form method="POST">
<!-- CSRF対策(トークンが生成される) -->
{{ form.hidden_tag() }}
<div>
{{ form.username.label }} {{ form.username() }}
# 追記
{% for error in form.username.errors %}
<span style="color: red;">{{ error }}</span>
{% endfor %}
</div>
<div>
{{ form.email.label }} {{ form.email() }}
# 追記
{% for error in form.email.errors %}
<span style="color: red;">{{ error }}</span>
{% endfor %}
</div>
<div>
{{ form.password.label }} {{ form.password() }}
# 追記
{% for error in form.password.errors %}
<span style="color: red;">{{ error }}</span>
{% endfor %}
</div>
<div>
{{ form.pass_confirm.label }} {{ form.pass_confirm() }}
</div>
{{ form.submit() }}
</form>
表示確認
以上、基本的なフォーム作成方法を説明しました。