Как импортировать пользовательские фильтры jinja2 из другого файла (и с помощью Flask)?
У меня есть файл jinja_filters.py с несколькими десятками пользовательских фильтров, которые я написал. Теперь у меня есть несколько приложений Flask, которым необходимо использовать эти фильтры. (Я не уверен, что моя проблема связана с флаконом или нет.)
Один хакерский способ выполнить то, что я хочу сделать:
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)
...
Какой "правильный" способ сделать это?
EDIT: В идеале мне не нужно будет перечислять каждое имя фильтра. Поэтому, когда я добавляю новый фильтр в jinja_filters.py, мне не нужно обновлять какой-либо другой код - все мои приложения смогут использовать его сразу.
Ответы
Ответ 1
Где бы вы ни настраивали свой объект приложения (возможно, 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
и т.д.
Другая возможность - использовать модуль 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 с помощью ваших фильтров.
Ответ 2
Существует рекомендуемый способ сделать это с помощью чертежей флажков. Одним из таких вариантов использования является эта функциональность:
- Предоставлять шаблонные фильтры, статические файлы, шаблоны и другие утилиты по чертежам. Проект не должен реализовывать приложения или просматривать функции.
Вам просто нужно создать объект flask.Blueprint
и использовать его для регистрации ваших фильтров так же, как с объектом приложения flask.Flask
, используя Blueprint.app_template_filter
decorator или 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)
И вуаля, фильтры зарегистрированы.