※この記事は、私が運営している技術ブログ(hirahira.blog)で公開していた内容を移植・加筆したものです。
FlaskとWTFormsを使ってシンプルなフォーム画面を作成する方法を解説します。
WTFormsとはFlaskでフォームを作成する際に使用されるライブラリです。
WTFormsを使うことにより、バリデーションやセキュリティ対策を簡単に行うことができます。
環境
- Windows 11
- Python 3.13.2
- Flask 3.1.0
- WTForms 3.2.1
準備
以下の2コマンドを実行して、FlaskとWTFormsをインストールしてください。
pip install flask
pip install wtforms
構成
以下の構成でフォルダとファイルを作成します。
├ app.py
└ templates/
├ register.html
├ registered.html
└ formhelpers.html
コード内容の解説
app.py
メインとなる処理を記述しています。
Registration
クラスで、各入力項目に対するバリデーション内容の定義を行っています。
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 Registration(Form):
name = StringField('名前:', validators=[DataRequired()])
age = IntegerField('年齢:', validators=[NumberRange(0, 100, '年齢は0から100の間で入力してください')])
password = PasswordField('パスワード:', validators=[
Length(1, 10, 'パスワードは1文字以上10文字以内で入力してください'),
EqualTo('re_password', 'パスワードが一致しません')
])
re_password = PasswordField('パスワード再入力:')
comment = TextAreaField('コメント:')
accept = BooleanField('内容確認:', validators=[DataRequired(message='内容確認にチェックを入れてください')])
submit = SubmitField('送信')
# POSTかつバリデーションエラーがない場合は、セッションに入力内容を格納してregistered.htmlを表示
@app.route('/', methods=['GET', 'POST'])
def index():
form = Registration(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('registered'))
return render_template('register.html', form=form)
@app.route('/registered')
def registered():
return render_template('registered.html')
if __name__ == '__main__':
app.run(debug=True)
register.html
入力フォーム画面です。
下で紹介するrender_field
マクロをインポートして使っています。
{{ form.csrf_token }}
は、CSRF(クロスサイトリクエストフォージェリ)対策用のトークンを生成するための記述です。
<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>
formhelpers.html
フォーム画面を整形し、エラー内容を表示する処理を、jinja2のマクロ機能を使って定義しています。
{{ field(**kwargs)|safe }}
のようにsafeを付けるとHTMLをエスケープせずに表示することができます。(WTForms側でエスケープしてくれる)
<!-- よく使用する処理をマクロ(関数)として定義 -->
{% 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 %}
registered.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>
動作確認
python app.py
を実行し、http://127.0.0.1:5000 にアクセスするとフォーム画面が表示されます。
不正な値を入力後に送信ボタンをクリックすると、エラーメッセージが表示されます。
正しい情報を入力して送信ボタンを押すとregisterd.html
に遷移し、入力した内容が表示されます。
参考記事