Использование функций Python в шаблонизаторе Jinja2
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Чтобы вызвать функцию Python из шаблона Jinja2, необходимо передать эту функцию в контекст рендеринга при использовании render_template
во Flask:
# Определите функцию
def greet(name):
return f"Привет, {name}"
# Передайте её в шаблон
return render_template('template.html', greet=greet)
# Вызовите функцию в шаблоне
# {{ greet('World') }}
Здесь функция greet
регистрируется, передаётся в template.html
и вызывается в шаблоне Jinja2.
Расширенное использование
Глобальная регистрация функций
Функции можно сделать доступными глобально во всех шаблонах, чтобы избежать повторения их определения для каждого отдельного шаблона:
# Присваиваем функции глобальный статус
app.jinja_env.globals['greet'] = greet
Теперь greet
может быть вызвана в любом шаблоне без дополнительной передачи.
Функции контекстных процессоров Flask для автоматической подачи данных
Контекстные процессоры Flask предоставляют возможность автоматически добавлять функции или переменные во всех шаблонах:
@app.context_processor
def utility_processor():
def format_price(amount, currency="$"):
return f"{currency}{amount:.2f}"
return dict(format_price=format_price)
Изоляция функций в модулях
Для структурирования кода удобно определить функции отдельно и импортировать их по мере необходимости:
# utilities.py
def compute_discount(price, discount):
return price – price * discount
В основном файле Python:
from utilities import compute_discount
app.jinja_env.globals['compute_discount'] = compute_discount
Передача определённых функций в шаблоны
Можно передать функции определённым шаблонам для их эксклюзивного использования:
return render_template('sales.html', compute_discount=compute_discount)
Пользовательские фильтры Jinja2
Создайте собственные фильтры Jinja для выполнения определённых задач:
@app.template_filter('topthree')
def topthree_filter(sequence):
return sequence[:3]
Загрузчики шаблонов Jinja2
Для загрузки шаблонов в Jinja2 используйте класс FileSystemLoader
:
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('/path/to/templates'))
env.globals['greet'] = greet
template = env.get_template('my_template.html')
print(template.render())
Версия Jinja2
Убедитесь, что используемые функции совместимы с используемой вами версией Jinja2:
import jinja2
print(jinja2.__version__)
Визуализация
Можно представить вызов функции Python в Jinja2 следующим образом:
Python 🐍 определяет функцию *encrypt_message*
Jinja2 🏰 желает использовать функцию *encrypt_message*
Взаимодействие между ними:
{{ encrypt_message('Секретный код') }}
Результат:
🏰 получает от 🐍 'Секретный код', преобразует и отправляет обратно ➡️ '*Зашифрованное сообщение*'
Процесс будет успешным, если функция определена в Python и передана в Jinja2.
Практические сценарии и подводные камни
Генерация динамического контента
Динамическую генерацию контента можно реализовать путем вызова функций обработки данных в шаблонах:
<ul>
{% for user in users %}
<li>{{ get_user_role(user) }}</li>
{% endfor %}
</ul>
Кэширование для улучшения производительности
Для увеличения скорости работы приложения используйте кэширование результатов функций. Это позволит избежать повторных расчетов данных при каждом запросе.
Сохранение лаконичности шаблонов
Стремитесь к минимализму в шаблонах, избегая замешательства сложными функциями. Следуйте принципу DRY (Don't Repeat Yourself — не повторяйся).
Разделение логики приложения
Логику приложения следует разделять на бизнес-логику и логику отображения: логику в шаблонах Jinja2 следует минимизировать, предоставив обработку данных функциям Python.