基本 Jinja

Jinja は文字列などの定数をうまくフィルターできないかも:レンダリングを内部キャッシュする

最終更新日 2023.03.06

Python の Flask で Jinja を使うとき、定数のフィルターは意図しない挙動をする場合があります。

<h1>{{ 'メールアドレスの変更' | trans }}</h1>

trans というフィルター(英語などに翻訳する関数)は Flask で定義されているとします。この trans はセッションや URL の変数をもとに文字列を翻訳します。つまりユーザーごとにフィルター後の結果は変わる。

しかし、Flask は最初のユーザーのためにテンプレートをレンダリングしたら、そのあとは二度とフィルターを考慮しません。これは

Calling template_filter function in flask only once?

で開発者が回答しています。

The first time the template is used, the filter is called. Subsequent renders use the cached version with the evaluated constsnt and the function is not called. If the value passed to the filter was not constant, the filter would be evaluated during each render instead. -davidism

フィルターにかけるものが定数だからです。変数であれば、Flask はテンプレートをキャッシュしない。

フィルターのキャッシュを無効にすると、今度は Flask のセッションがクッキーとして送信されなくなる

定数のフィルターキャッシュを無効にするには

app.jinja_options['cache_size'] = 0

とします。数時間も調べた結果、これ以外の方法は見つかりませんでした。上のようにすると、テンプレートのキャッシュが無効になるため、リクエストごとに定数もフィルターにかかります。

しかし、今度はセッションクッキーがおかしくなる。正確には、セッションオブジェクトは正常に機能するが、クッキーがユーザーに送信されなくなる。

最初はセッションに無駄な情報が入り、サイズが大きくなって送信されなくなったのかと思いました。しかしそうではない。セッションオブジェクトは問題ない。また、他のクッキーは送信されているので、クッキーの問題でもない。

セッションの送信がテンプレートのキャッシュとなにかつながっている可能性があります。もしなにか解決策があったらご連絡をお願いします!