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

一つ前のページでは色々な便利フィルターについて学習しました。
今回は カスタムフィルター について見ていきましょう。
Chapter1:Flask入門編
Chapter2:Jinja2入門編
Chapter3:フィルター編
・Chapter3-1:フィルターの基本を理解しよう
・Chapter3-2:色々なフィルターを使ってみよう
・Chapter3-3:カスタムフィルターを理解しよう ◁今回はここ
Chapter4:フォーム編
Chapter5:データベース編
Chapter6:Flaskの便利機能編
Chapter7:アプリ開発編
Flaskでテンプレートを使ってWebページを作る際、データを表示するだけでなく、ちょっとした加工を加えたい場面があります。
例えば、文字列の見た目を変えたり、特定の形式に変換したり…。そういったときに活躍するのが「フィルター」です。
これまでの章では、すでに用意されているフィルターを使う方法を紹介してきましたが、「自分でフィルターを作る」ことも可能です。
今回は、そんな カスタムフィルター の作成方法を学びます。
カスタムフィルターとは何か?
カスタムフィルターとは、Flaskで自分だけの独自フィルターを作ってテンプレートで使えるようにする仕組みです。
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のカスタムフィルターで一工夫してみよう
この問題では、テンプレートに用意された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>
また、以下のような実行結果となるコードを書くこと。
佐藤様、こんにちは!
正解コード
例えば、以下のようなプログラムが考えられます。
- 正解コード
-
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)
正解コードの詳細解説
正解コードをブロックごとに分割して解説します。
- 正解コードの詳細解説
-
タイトル
説明文
タイトル
説明文
FAQ|Jinja2のカスタムフィルター活用編
- Q1. Flaskで作ったカスタムフィルターは複数のテンプレートで使えますか?
-
はい、同じFlaskアプリ内であれば、定義したカスタムフィルターはすべてのテンプレートで再利用できます。共通のフィルターを作ることで、コードの保守性も高まります。
- Q2. カスタムフィルターの定義はアプリのどこに書くのがベストですか?
-
一般的には、
app.py
などのFlaskアプリケーション本体に記述します。複雑なプロジェクトでは、専用のモジュールやfilters.py
などに分けて管理するのがおすすめです。
- Q3. カスタムフィルターの名前に制限はありますか?
-
Pythonの関数名と同様に、アルファベットとアンダースコアを使った名前が推奨されます。すでに存在するJinja2の組み込みフィルター名とは被らないようにしましょう。
質問用コンタクトフォーム
この記事を書くにあたりAIを活用しています。
人間の目による確認も行っていますが、もし間違い等ありましたらご指摘頂けると大変助かります。