【Python】Flask+WTFormsで簡単にフォームを作成する

Python

今回は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/にアクセスするとフォーム画面が表示されます。

f:id:canos:20200725121040p:plain

不正な値を入力すると、エラーメッセージが表示されます。

f:id:canos:20200725121222p:plain

正しく情報を入力して「submit」ボタンを押すとregisterd.htmlに遷移し、入力内容が表示されます。

f:id:canos:20200725121444p:plain

参考

Form Validation with WTForms(Flask公式ドキュメント)
https://flask.palletsprojects.com/en/1.1.x/patterns/wtforms/

FlaskFormで簡単にバリデーションする方法
https://qiita.com/kotamatsuoka/items/c93129f6ade5974dc122

おすすめ教材

Flaskを0から学ぶなら以下のUdemy講座がとてもおすすめです。

Python+FlaskでのWebアプリケーション開発講座!!~0からFlaskをマスターしてSNSを作成する~

コメント

タイトルとURLをコピーしました