Как импортировать пользовательские фильтры jinja2 из другого файла (и с помощью Flask)? - программирование

Как импортировать пользовательские фильтры 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, мне не нужно обновлять какой-либо другой код - все мои приложения смогут использовать его сразу.

4b9b3361

Ответ 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)

И вуаля, фильтры зарегистрированы.