Flask入門|Jinja2カスタムフィルターでテンプレートに独自機能を追加しよう【チャプター3-03】

ながみえ

一つ前のページでは色々な便利フィルターについて学習しました。

今回は カスタムフィルター について見ていきましょう。

Chapter1:Flask入門編
Chapter2:Jinja2入門編
Chapter3:フィルター編

 ・Chapter3-1:フィルターの基本を理解しよう
 ・Chapter3-2:色々なフィルターを使ってみよう
 ・Chapter3-3:カスタムフィルターを理解しよう ◁今回はここ
Chapter4:フォーム編
Chapter5:データベース編
Chapter6:Flaskの便利機能編
Chapter7:アプリ開発編

Flaskでテンプレートを使ってWebページを作る際、データを表示するだけでなく、ちょっとした加工を加えたい場面があります。

例えば、文字列の見た目を変えたり、特定の形式に変換したり…。そういったときに活躍するのが「フィルター」です。

これまでの章では、すでに用意されているフィルターを使う方法を紹介してきましたが、「自分でフィルターを作る」ことも可能です。

今回は、そんな カスタムフィルター の作成方法を学びます。

<<前のページ

Flaskの記事一覧

次のページ>>

カスタムフィルターとは何か?

カスタムフィルターとは、Flaskで自分だけの独自フィルターを作ってテンプレートで使えるようにする仕組みです。

【Python】勉強猫がノートパソコンを前にして学習を始める様子。記事内の学習スタート用イラスト

Flaskで独自フィルターを作るメリットとは?

これまで学習してきたように、テンプレートで値を加工するには次のような形で書きます:

{{ name | upper }}

このように upper フィルターを使えば、文字列がすべて大文字に変換されます。

これと同じように、「自分で定義した名前のフィルター」を | を使って呼び出せるようになるのがカスタムフィルターのポイントです。

例えば「名前の後ろに “さん” をつけたい」という独自ルールがある場合、
{{ name | add_san }} のように書けたら便利ですよね。

こういった処理をPythonコードで自由に定義できるのがカスタムフィルターです。

基本文法と定義の仕方を初心者向けに解説

カスタムフィルターは次のように定義します。

@app.template_filter("フィルター名")
def 任意の関数名(受け取る値):
    # 加工して返す処理
    return 加工後の値
  • @app.template_filter("フィルター名") は、この関数がテンプレート用のフィルターであることをFlaskに伝えます。
  • "フィルター名" はテンプレート内で | のあとに使う名前です。
  • その下に定義する関数が実際の処理を担当します。

カスタムフィルターの使用例

では、実際に「文字列の後ろに“さん”をつけるフィルター」を作ってみましょう。

以下のコードをコピーして保存し、実行してください。

from flask import Flask, render_template
app = Flask(__name__)

# カスタムフィルターを定義
@app.template_filter("add_san")  # テンプレート側では「add_san」として使用できるようになる
def add_san_filter(name):
    # 引数として受け取った文字列の末尾に「さん」をつけて返す
    return name + "さん"

@app.route("/") # もしこのURLにアクセスされたら
def index():
    user_name = "田中"
    return render_template("index.html", name=user_name)

if __name__ == "__main__":
    app.run(debug=True)
<!DOCTYPE html>
<html>
<head>
    <title>カスタムフィルターの例</title>
</head>
<body>
    <p>こんにちは、{{ name | add_san }}!</p>
</body>
</html>

このコードを実行すると「こんにちは、田中さん!」と表示されます。

このように、テンプレート内で {{ name | add_san }} と書くだけで、Pythonで定義した関数が裏で実行されます。

まとめ

今回はテンプレートエンジンJinja2の機能をさらに活用するための、カスタムフィルターの作り方を学びました。

  • @app.template_filter("名前") を使って独自のフィルターを定義できる
  • 定義したフィルターは「| フィルター名」で呼び出せる

テンプレートでの表現力がさらに広がるカスタムフィルター。慣れてくると「自分だけのテンプレート記法」を作れる楽しさがあります。

ぜひ、オリジナルのフィルターを作ってみてください!

練習問題:Flaskのカスタムフィルターで一工夫してみよう

【Python】勉強猫がノートパソコンに向かい、練習問題に挑戦する様子。記事内の休憩用イラスト

この問題では、テンプレートに用意されたHTMLファイルをもとに、Flaskアプリ側に必要なコードを作成します。

テンプレート内で使われている add_sama フィルターを、Python側で定義し機能するようにしてください。

この問題の要件

以下の要件をすべて満たすように app.py を作成してください。

  • @app.template_filter("add_sama") デコレーターを使用して、テンプレートで使用できるカスタムフィルター add_sama を定義すること。
  • add_sama フィルターでは、引数として渡された名前の末尾に「様」を付けて返す関数を実装すること。
  • ルートパス(/)にアクセスしたときに、"佐藤" という名前をテンプレートに渡すこと。

ただし、以下のテンプレートを使用することを前提とする。

<!-- templates/hello.html -->
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>カスタムフィルター練習</title>
</head>
<body>
    <!-- カスタムフィルター「add_sama」を使って名前を丁寧な表現に変換 -->
    <p>{{ name | add_sama }}、こんにちは!</p>
</body>
</html>

また、以下のような実行結果となるコードを書くこと。

佐藤様、こんにちは!

正解コード

例えば、以下のようなプログラムが考えられます。

Q
正解コード
from flask import Flask, render_template

# Flaskアプリケーションを作成
app = Flask(__name__)

# カスタムフィルターを定義
@app.template_filter("add_sama")  # テンプレート内で使うフィルター名は "add_sama"
def add_sama_filter(name):
    """
    この関数は、与えられた名前の後ろに「様」をつけて返します。
    これはテンプレートで「お客様への丁寧な呼び方」に使えます。
    """
    return name + "様"

# ルートページにアクセスがあったときの処理
@app.route("/")
def index():
    # 表示したい名前(ここでは静的に "佐藤" としています)
    user_name = "佐藤"

    # テンプレートに user_name を渡して表示
    return render_template("hello.html", name=user_name)

# Flaskアプリの起動
if __name__ == "__main__":
    app.run(debug=True)

正解コードの詳細解説

正解コードをブロックごとに分割して解説します。

Q
正解コードの詳細解説

タイトル

説明文

タイトル

説明文

<<前のページ

Flaskの記事一覧

次のページ>>

FAQ|Jinja2のカスタムフィルター活用編

Q
Q1. Flaskで作ったカスタムフィルターは複数のテンプレートで使えますか?

はい、同じFlaskアプリ内であれば、定義したカスタムフィルターはすべてのテンプレートで再利用できます。共通のフィルターを作ることで、コードの保守性も高まります。

Q
Q2. カスタムフィルターの定義はアプリのどこに書くのがベストですか?

一般的には、app.pyなどのFlaskアプリケーション本体に記述します。複雑なプロジェクトでは、専用のモジュールやfilters.pyなどに分けて管理するのがおすすめです。

Q
Q3. カスタムフィルターの名前に制限はありますか?

Pythonの関数名と同様に、アルファベットとアンダースコアを使った名前が推奨されます。すでに存在するJinja2の組み込みフィルター名とは被らないようにしましょう。

質問用コンタクトフォーム

この記事を書くにあたりAIを活用しています。

人間の目による確認も行っていますが、もし間違い等ありましたらご指摘頂けると大変助かります。

記事URLをコピーしました