11-Flask

Flask(Part.7)| 【Flask-WTFを利用したバリデーション】

python| まとめ | 現役エンジニア&プログラミングスクール講師「python」のまとめページです。pythonに関して抑えておきたい知識や文法やにについて記事をまとめています。まとめページの下部には「おすすめの学習書籍」「おすすめのITスクール情報」「おすすめ求人サイト」について情報を掲載中...

目標

  • Flaskのルーティングを利用した小規模アプリを作成できる。
  • フォームからサーバーに送られてきたパラメータを検証することができる。

フォームを利用できる。
ここでは、Flask-WTFを利用した、バリデーションの実装を行います。

Flaskのルーティングを利用した小規模アプリの作成

Flask-WTFライブラリの概要とインストール

Flask-WTFライブラリの概要

Flask-WTFは、FlaskとWTFormsを統合する拡張機能で、フォームの作成や管理、バリデーション、CSRF対策などの機能を提供します。

バリデーションとは、ユーザーが送信するデータが期待する形式や条件を満たしているかを確認する処理です。Flaskにはいくつかのバリデーション方法がありますが、Flask-WTF(WTForms)を使用する方法が一般的です。他にも、request.form を手動で処理する方法や、marshmallow などのライブラリを使う方法もあります。

フォームのバリデーション機能は、ユーザーが入力したデータが期待される形式や条件を満たしているかを確認するために重要です。Flask-WTFを使うことで、フォームのフィールド、バリデーション、エラーメッセージの管理を簡単に行うことができます。また、CSRF保護やエラーハンドリングも自動的に提供されます。フォームのバリデーションは、ユーザーの誤入力を防ぎ、アプリケーションの品質とセキュリティを向上させます。

Flask-WTFのインストールとセットアップ


Flask-WTFをインストールします。

C:\Users\user\Desktop\FlaskProj>.venv\Scripts\activate

# 仮想環境が有効化されます。
(venv) C:\Users\user\Desktop\FlaskProj>pip install flask-wtf

FlaskアプリケーションでFlask-WTFを使用するためにインポートします。(クラスの作成時にインポートします。)

from flask_wtf import FlaskForm
from wtforms import StringField, IntegerField
from wtforms.validators import DataRequired, NumberRange

Flask-WTFライブラリの利用

フォームクラスの定義

Flask-WTFを使うと、フォームはPythonのクラスとして定義されます。フォームに必要なフィールド(例えば商品名、価格など)と、そのフィールドに対するバリデーションをクラスで定義します。

以下は、商品追加フォームです。商品名には必須の入力バリデーション、価格には数値としての制限を設けています。

forms.pyファイルの作成

forms.pyファイルをminiappディレクトリに作成します。

forms.pyファイルに次のプログラムを入力します。

from flask_wtf import FlaskForm
from wtforms import IntegerField, StringField
from wtforms.validators import DataRequired, NumberRange


class AddProductForm(FlaskForm):
    product_name = StringField("商品名", validators=[DataRequired()])
    product_price = IntegerField(
        "価格",
        validators=[
            DataRequired(),
            NumberRange(min=1, message="価格は1以上である必要があります"),
        ],
    )


FlaskForm:Flask-WTFのフォームクラスです。フォームを作成する際に継承します。
StringField:文字列を入力するためのフィールドです(商品名用)。
IntegerField:整数を入力するためのフィールドです(価格用)。
validators:入力値のバリデーション(検証ルール)を設定するためのクラスです。
DataRequired():値が空でないことを保証します。
NumberRange(min=1, message=”価格は1以上である必要があります”):
min=1:価格の値が1以上であることを保証します。
message:条件を満たさない場合に表示されるエラーメッセージを指定します。

Flaskビューでのフォームの利用方法

Flaskビューでのフォームの利用方法

次に、Flaskビューでフォームを利用します。フォームが正常に送信された場合に、データを処理してリダイレクトする処理を行います。

Flaskビューとフォームビュー

Flaskのビュー(ビュー関数)は、リクエストを受け取り、適切なレスポンス(HTMLページやJSONデータなど)を返す関数のことです。通常、@app.route() デコレーターを使ってルート(URL)に紐づけられます。

フォームビューは、Flaskビューの中でも フォームの表示、データの受け取り、バリデーション、処理 を行うものです。主に Flask-WTF を使って実装されます。

from flask import Flask, redirect, render_template, url_for

from apps.miniapp.forms import AddProductForm

app = Flask(__name__)
app.secret_key = "your_secret_key"

# 商品リスト
products = [
    {"id": 1, "name": "オレンジジュース", "price": 140},
    {"id": 2, "name": "アップルジュース", "price": 150},
    {"id": 3, "name": "牛乳", "price": 180},
]


@app.route("/")
def index():
    return "Top page"


@app.route("/products")
def product_list():
    return render_template("products.html", products=products)


@app.route("/add_product", methods=["GET", "POST"])
def add_product():
    form = AddProductForm()

    if form.validate_on_submit():
        # フォームが送信されて、かつバリデーションが成功した場合
        name = form.product_name.data
        price = form.product_price.data

        # 新しい商品を追加
        new_id = len(products) + 1
        products.append({"id": new_id, "name": name, "price": price})

        # 商品一覧ページにリダイレクト
        return redirect(url_for("product_list"))

    return render_template("add_product.html", form=form)


@app.route("/manage_products")
def manage_products():
    # 商品管理ページを表示
    return render_template("manage_products.html")


if __name__ == "__main__":
    app.run(debug=True)

フォームの処理は次の手順で行っています。

フォームオブジェクトの作成

form = AddProductForm()でフォームオブジェクトを作成します。

フォームの送信とバリデーション

form.validate_on_submit()は、フォームがPOSTリクエストとして送信され、かつバリデーションが成功した場合にTrueを返します。これをif文の条件に設定することで、適切な場合に処理を行わせることが可能となります。

フォームデータへのアクセス

フォームのデータは、form.name.dataやform.price.dataでアクセスできます。

エラーメッセージの表示

バリデーションが失敗した場合、フォームにはエラーメッセージが表示されます。form.errorsを使って各フィールドのエラーメッセージを取得できます。

HTMLテンプレートでのフォーム表示

Flask-WTFを使ってフォームを表示する場合、Jinja2テンプレートエンジンを使って、フォームのフィールドとエラーメッセージを表示します。

add_product.htmlの商品追加フォームの内容を編集します。

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>商品追加</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>

<body>

    <h1>商品追加ページ</h1>
    <ul>
        <li><a href="{{ url_for('product_list') }}" class="button-link">商品一覧に戻る</a></li>
        <li><a href="{{ url_for('manage_products') }}" class="button-link">商品管理ページ</a></li>
    </ul>

    <h1>商品追加フォーム</h1>

    <form method="POST" action="{{ url_for('add_product') }}">
        {{ form.hidden_tag() }} <!-- CSRFトークンを含めるため -->

        <label for="product_name">商品名</label>
        {{ form.product_name() }} <!-- 商品名入力フィールド -->
        {% if form.product_name.errors %}
        <ul>
            {% for error in form.product_name.errors %}
            <li>{{ error }}</li>
            {% endfor %}
        </ul>
        {% endif %}

        <label for="product_price">価格</label>
        {{ form.product_price() }} <!-- 価格入力フィールド -->
        {% if form.product_price.errors %}
        <ul>
            {% for error in form.product_price.errors %}
            <li>{{ error }}</li>
            {% endfor %}
        </ul>
        {% endif %}

        <input type="submit" value="商品を追加する">
    </form>

</body>

</html>
<form method=”POST”>の部分

<form method=”POST” action=”{{ url_for(‘add_product’) }}”> としてPOSTメソッドと送信先URLを指定しています。

{{ form.name() }}や{{ form.price() }}は、Flask-WTFで定義されたフォームフィールドを表示(利用)する部分です。form.hidden_tag()は、CSRF(クロスサイトリクエストフォージェリ)保護用の隠しタグを挿入します。フォームのバリデーションが失敗した場合は、form.name.errorsやform.price.errorsでエラーメッセージを取得し、テンプレート内で表示します。

バリデーションエラーメッセージのカスタマイズ

バリデーションエラーメッセージは、バリデータで指定することができます。例えば、NumberRange(min=1)では、価格が1未満の場合にカスタムメッセージを表示させることができます。

price = IntegerField('価格', validators=[DataRequired(), NumberRange(min=1, message="価格は1以上である必要があります")])
CSRF保護

Flask-WTFでは、デフォルトでCSRF(クロスサイトリクエストフォージェリ)保護が有効になります。これにより、フォームの送信時にCSRFトークンが必要となり、不正なリクエストを防ぐことができます。form.hidden_tag()はこのトークンをフォームに埋め込む役割を担っています。

ブラウザで http://127.0.0.1:5000/manage_productsにアクセスします。

商品管理ページが表示されます。


商品一覧ボタンを押下すると、商品一覧ページが表示されます。

商品を追加するボタンを押下すると、商品追加ページが表示されます。

商品名と価格を入力して「商品を追加する」ボタンを押下します。

http://127.0.0.1:5000/products にリダイレクトされます。

商品が追加されています。

続けて、商品追加ページで商品名を空で送信ボタンを押下します。

商品の追加はされず、商品追加ページが再表示されます。

今回は以上になります。

「python」おすすめ書籍 ベスト3 | 現役エンジニア&プログラミングスクール講師「python」の学習でお勧めしたい書籍をご紹介しています。お勧めする理由としては、考え方、イメージなどを適切に捉えていること、「生のpython」に焦点をあてて解説をしている書籍であることなどが理由です。勿論、この他にも良い書籍はありますが、特に質の高かったものを選んで記事にしています。ページの下部には「おすすめのITスクール情報」「おすすめ求人サイト」について情報を掲載中。...

ブックマークのすすめ

「ほわほわぶろぐ」を常に検索するのが面倒だという方はブックマークをお勧めします。ブックマークの設定は別記事にて掲載しています。

「お気に入り」の登録・削除方法【Google Chrome / Microsoft Edge】「お気に入り」の登録・削除方法【Google Chrome / Microsoft Edge】について解説している記事です。削除方法も掲載しています。...
【パソコン選び】失敗しないための重要ポイント | 現役エンジニア&プログラミングスクール講師【パソコン選び】失敗しないための重要ポイントについての記事です。パソコンのタイプと購入時に検討すべき点・家電量販店で見かけるCPUの見方・購入者が必要とするメモリ容量・HDDとSSDについて・ディスプレイの種類・バッテリーの持ち時間や保証・Officeソフト・ウィルス対策ソフトについて書いています。...
RELATED POST
11-Flask

Flask(Part.2)| 【MVTの概要とアプリケーションの起動方法 】

2025年2月13日
プログラミング学習 おすすめ書籍情報発信 パソコン初心者 エンジニア希望者 新人エンジニア IT業界への就職・転職希望者 サポートサイト Programming learning Recommended schools Recommended books Information dissemination Computer beginners Prospective engineers New engineers Prospective job seekers in the IT industry Support site