Jinja2では、フィルター(Filter) を使うことで、表示するデータを加工できます。 Pythonでデータを加工しなくても、HTML内で簡単に文字列やリストを変換 できます!
そんなフィルターについて紹介していきます。
目次
フィルターの実装方法
フィルターの実装方法には二種類あります。方法は二つあり、パイプ (|
) を使う方法とfilter
ブロックを使う
方法がありますので紹介していきます。
今回のディレクトリ構成は下記の通りです。
your_project/
│
├── app.py
└── templates/
└── index.html
パイプ (|
) でフィルターをかける
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
data = {
'text': "Hello World",
'sentence': "flask is great",
'html_text': "<b>重要</b>",
}
return render_template('index.html', data=data)
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flask Filters Example</title>
</head>
<body>
<h1>Flask Filters Example</h1>
<!-- 大文字に変換 -->
<p>Upper: {{ data.text | upper }}</p>
<!-- 小文字に変換 -->
<p>Lower: {{ data.text | lower }}</p>
<!-- 最初の文字を大文字にして残りは小文字に変換 -->
<p>Capitalize: {{ data.sentence | capitalize }}</p>
<!-- 各単語の最初の文字を大文字に変換 -->
<p>Title: {{ data.sentence | title }}</p>
<!-- 'World'を'Flask'に置き換え -->
<p>Replace: {{ data.text | replace('World', 'Flask') }}</p>
<!-- 文字列の前後の空白を削除 -->
<p>Trim: {{ ' hello ' | trim }}</p>
<!-- HTMLタグを取り除く -->
<p>StripTags: {{ data.html_text | striptags }}</p>
<!-- 単語数をカウント -->
<p>WordCount: {{ data.text | wordcount }}</p>
</body>
</html>
{{ データ| フィルター }}という使い方でデータに対してフィルターをかけることが出来ます。↑のコードを実際に試していただいたら表のように変わると思います。このパイプのやり方が一般的かと思います。
{% filter %}
ブロックでフィルターかける
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flask Filters Example</title>
</head>
<body>
<h1>Flask Filters Example</h1>
<p>
{% filter upper %}
{{ data.sentence }}
{% endfilter %}
</p>
</body>
</html>
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
data = {
"sentence": "this is a sentence to be filtered."
}
return render_template('index.html', data=data)
if __name__ == '__main__':
app.run(debug=True)
{% filter フィルター名 %} : {% endfilter %}
Flaskのテンプレートエンジン(Jinja2)でフィルターを適用するための便利な方法です。この{% filter %}
ブロックを使うと、複数行のテキストなどにフィルターを適用します。
ただ正直言うとあんまり使う機会はないかと思います。{{ variable | upper }}などパイプを使って書くだけで、十分事足りるというのが本音ではあるので、余裕があれば覚えるぐらいで、使うときは確認のためにこのサイト訪れるぐらいでいいと思います。
カスタムフィルター
from flask import Flask, render_template
import random
app = Flask(__name__)
# ランダムに選ばれるアイテムのリスト(ガチャのアイテム)
gacha_items = ['スーパーレアアイテム', 'レアアイテム', 'ノーマルアイテム', 'ハズレ']
# リストからランダムに要素を取得するフィルター
def random_item(value):
if isinstance(value, list) and value:
return random.choice(value)
return value
# カスタムフィルターをFlaskアプリケーションに登録
app.jinja_env.filters['random_item'] = random_item
@app.route('/')
def index():
# ガチャアイテムを引く
item = gacha_items
return render_template('index.html', item=item)
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ガチャアプリ</title>
</head>
<body>
<h1>ガチャを引いてみよう!</h1>
<p>あなたのガチャ結果は…</p>
<p>{{ item | random_item }}</p> <!-- ランダムなアイテムを表示 -->
<button onclick="window.location.reload();">もう一度引く</button>
</body>
</html>
Flaskでは、作成したカスタムフィルターをapp.jinja_env.filters
に登録することで、使えるようにします。フィルターを登録するには、jinja_env.filters
にフィルター関数を追加します。
使い方はパイプやfliterブロックなど通常のフィルターの使い方ができます。↑のカスタムフィルターに関してはリストの中からランダムに抽出するというものです。ガチャなんかのランダム要素は必要な時に使いやすいんじゃないかと思います。
実際に使ってみる
カスタムフィルターを使うことで簡易的ではありますが、ガチャを作ることが出来ました。こういったカスタムフィルターを使うことで、便利になることはなんとなくわかったと思います。ぜひご自身のオリジナルカスタムフィルター作ってみてくださいね。
フィルター一覧
フィルターがほかのflaskの機能と比べて使う機会がそこまで多くないと思います。代表的なフィルターを紹介したのでほかも使ってみたいという人向けに表にしたのでご活用ください。
batch リストを指定したサイズごとのグループに分割する
default 値が未定義または空のときにデフォルト値を設定する
escape 文字列のHTMLエスケープを行う (< や > を < や > に変換)
filesizeformat バイト単位の数値を人間が読みやすい形式 (KB, MB) に変換する
forceescape すでにエスケープされている文字列を再エスケープする
groupby 指定したキーでリストをグループ化する
pprint 人間が読みやすい形でオブジェクトを整形表示する
random リストの中からランダムな要素を取得する
rejectattr オブジェクトの属性に基づいて要素を除外する
selectattr オブジェクトの属性に基づいて要素を抽出する
striptags 文字列からHTMLタグを削除する
xmlattr 辞書のキーと値をXML属性形式に変換する