今回はFlaskとWTFormsを使ってシンプルなフォーム画面を作成してみます。
WTFormsとはFlaskでフォームを作成する際に使用されるライブラリです。
これを使うことにより、バリデーション(ユーザーが入力した内容が正しいかどうかをチェックする機能)やセキュリティ対策を簡単に行うことができます。
環境
- Windows 10
- Python 3.8.3
- Flask 1.1.1
準備
まずは「pip install wtforms」でWTFormsをインストールしましょう。
構成
├ app.py
└ templates/
├ register.html
├ registered.html
└ formhelpers.html
コードの中身
app.py
from flask import Flask, redirect, render_template, request, session, url_for
# Formクラス及び使用するフィールドをインポート
from wtforms import (
Form, BooleanField, IntegerField, PasswordField, StringField,
SubmitField, TextAreaField)
# 使用するvalidatorをインポート
from wtforms.validators import DataRequired, EqualTo, Length, NumberRange
app = Flask(__name__)
# セッションで使用するシークレットキーを設定。本来はランダムな文字列が望ましい
app.config[‘SECRET_KEY’] = ‘secret_key’
# wtformsのFormクラスを継承。それぞれの入力項目に対してバリデーションチェックをかける
class Ragistration(Form):
name = StringField(‘名前:’, validators=[DataRequired()])
age = IntegerField(‘年齢:’, validators=[NumberRange(0, 100, ‘不正な値です’)])
password = PasswordField(‘パスワード:’, validators=[
Length(1, 10, ‘長さは1文字以上10文字以内です’),
EqualTo(‘re_password’, ‘パスワードが一致しません’)])
re_password = PasswordField(‘パスワード再入力:’)
comment = TextAreaField(‘コメント:’)
accept = BooleanField(‘内容確認:’)
submit = SubmitField(‘Submit’)
# POSTかつバリデーションエラーがない場合は、セッションに入力内容を格納してregistered.htmlを表示
@app.route(‘/’, methods=[‘GET’, ‘POST’])
def index():
form = Ragistration(request.form)
if request.method == ‘POST’ and form.validate():
session[‘name’] = form.name.data
session[‘age’] = form.age.data
session[‘comment’] = form.comment.data
return redirect(url_for(‘registerd’))
return render_template(‘register.html’, form=form)
@app.route(‘/registered’)
def registerd():
return render_template(‘registered.html’)
if __name__ == ‘__main__’:
app.run(debug=True)
register.html
<html lang=“ja”>
<head>
<meta charset=“UTF-8“ />
<title>Form</title>
</head>
<body>
<!– formhelpers.htmlで定義したrender_fieldマクロをインポート –>
{% from “formhelpers.html” import render_field %}
<form method=“POST”>
{{ form.csrf_token }}
{{ render_field(form.name) }}
{{ render_field(form.age) }}
{{ render_field(form.password) }}
{{ render_field(form.re_password) }}
{{ render_field(form.accept) }}
{{ render_field(form.comment) }}
{{ form.submit() }}
</form>
</body>
</html>
登録画面です。
{{ form.csrf_token }}で、簡単にCSRF(クロスサイトリクエストフォージェリ)対策用のトークンを生成できるようです。
formhelpers.html
<!– よく使用する処理をマクロ(関数)として定義 –>
{% macro render_field(field) %}
<dt>{{ field.label }}</dt>
<dd>{{ field(**kwargs)|safe }}</dd>
{% if field.errors %}
<ul class=“error”>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
公式ドキュメントからそのまま引用しています。
フォーム画面の整形し、エラー内容を表示する処理をjinja2のマクロ機能を使ってまとめています。
※{{ field(**kwargs)|safe }}
safeを付けることで、HTMLをエスケープせずに表示することができます。
WTFormsで既にエスケープ済みのためこのように記述するようです。
registered.html
<!DOCTYPE html>
<html lang=“ja”>
<head>
<meta charset=“UTF-8“ />
<title>registerd</title>
</head>
<body>
<h1>登録内容</h1>
<ul>
<li>名前:{{ session[‘name’] }}</li>
<li>年齢:{{ session[‘age’] }}</li>
<li>コメント:{{ session[‘comment’] }}</li>
</ul>
</body>
</html>
登録された内容を画面に表示します。
実行結果
app.py実行後にhttp://localhost:5000/にアクセスするとフォーム画面が表示されます。
不正な値を入力すると、エラーメッセージが表示されます。
正しく情報を入力して「submit」ボタンを押すとregisterd.htmlに遷移し、入力内容が表示されます。
参考
Form Validation with WTForms(Flask公式ドキュメント)
https://flask.palletsprojects.com/en/1.1.x/patterns/wtforms/
FlaskFormで簡単にバリデーションする方法
https://qiita.com/kotamatsuoka/items/c93129f6ade5974dc122