web-dev-qa-db-ja.com

カスタムjinja2フィルターを別のファイルから(そしてFlaskを使用して)インポートする方法は?

私が書いた数十のカスタムフィルターを含むjinja_filters.pyファイルがあります。現在、これらのフィルターを使用する必要がある複数のFlaskアプリがあります(問題がFlask固有であるかどうかはわかりません)。

私がやりたいことを達成するための1つのハッキーな方法は次のことです。

app = Flask(__name__)

import jinja_filters

@app.template_filter('filter_name1')
def filter_name1(arg):
    return jinja_filters.filter_name1(arg)

@app.template_filter('filter_name2')
def filter_name2(arg):
    return jinja_filters.filter_name2(arg)

...

これを行うための「正しい」方法は何ですか?

編集:理想的には、各フィルター名をリストする必要はありません。したがって、jinja_filters.pyに新しいフィルターを追加するときに、他のコードを更新する必要はありません。すべてのアプリですぐに使用できます。

19
Dustin Boswell

アプリオブジェクト(おそらくapp.py)を設定する場合は常に、カスタムフィルターをインポートしてから、Jinja環境属性を変更するだけで済みます。

import jinja_filters

app = Flask(__name__)
app.jinja_env.filters['filter_name1'] = jinja_filters.filter_name1
app.jinja_env.filters['filter_name2'] = jinja_filters.filter_name2

等々。

もう1つの可能性は、inspectモジュールを使用して、次のようにjinja_filters内のすべてのメソッドを検索することです。

from inspect import getmembers, isfunction
import jinja_filters

app = Flask(__name__)

my_filters = {name: function 
                for name, function in getmembers(jinja_filters)
                if isfunction(function)}

app.jinja_env.filters.update(my_filters)

そのコードはテストされていませんが、jinja_filtersファイルに存在する関数名と関数の辞書を作成してから、Jinja環境のフィルター辞書をフィルターで更新するというアイデアがあります。

26
aezell

Flaskブループリント を使用してこれを行うための推奨される方法があります。そのユースケースの1つは、特にこの機能です。

  • ブループリントを介して、テンプレートフィルター、静的ファイル、テンプレート、およびその他のユーティリティを提供します。ブループリントは、アプリケーションを実装したり、機能を表示したりする必要はありません。

flask.Blueprint オブジェクトを作成し、それを使用して、flask.Flask appオブジェクトの場合と同様に、 Blueprint.app_template_filter デコレータまたは Blueprint.add_app_template_filter メソッド。

# filters.py

import jinja2
import flask

blueprint = flask.Blueprint('filters', __name__)

# using the decorator
@jinja2.contextfilter
@blueprint.app_template_filter()
def filter1(context, value):
    return 1

# using the method
@jinja2.contextfilter
def filter2(context, value):
    return 2

blueprint.add_app_template_filter(filter2)

次に、アプリオブジェクトにブループリントを登録する必要があります。

# app.py

import flask
import filters

app = flask.Flask(__name__)
app.register_blueprint(filters.blueprint)

そして、voilà、フィルターが登録されています。

36
famousgarkin