4
4

More than 1 year has passed since last update.

【Flask】Flask_WTFを使ってフォーム作成してみた

Posted at

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" をパスパラメータに付けてブラウザ表示する。
名前などフォームに入れて、送信。
image.png

上記の画面で送信すると、リダイレクト先のユーザー管理画面に遷移する。
新規登録ページで入力した、名前とメールアドレスが表示される。
image.png

バリデーション設定を追記

フォームに入力した内容がルールに反していた場合に、エラー表示されるよう、コードを追記

インポート

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>

表示確認

  • メールアドレスを正しい形式で入力していない
  • パスワードとパスワード(確認)が一致していない
    image.png

以上、基本的なフォーム作成方法を説明しました。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4