Jinja2: локальная/глобальная переменная
{% set disabled = '' %}
{% for voter in record.voters %}
{% if user == voter %}
{% set disabled = 'disabled' %}
{% endif %}
{{ disabled }} # outputs: 'disabled'
{% endfor %}
{{ disabled }} # outputs: ''
У меня есть этот шаблон в Jinja2. Что мне нужно, так это "отключенная" переменная, которая будет видна снаружи цикла "for". Это возможно?
4 ответов
самый простой способ справиться с этим-переместить логику, которая устанавливает disabled
переменная для вашей функции просмотра и отправьте ее в шаблон, готовый к использованию. Смешивание логики приложения с презентацией не является хорошей идеей, шаблоны должны получать данные как можно более переваренными.
тем не менее, есть уродливый хак, который делает возможным то, что вы хотите, показано в принятом ответе на этот вопрос.
решение включает в себя включение do
расширение для Jinja2 и использование его для изменения глобального массива. Для включения расширения используйте:
app.jinja_env.add_extension('jinja2.ext.do')
вот решение, адаптированное к вашему примеру:
{% set disabled = [] %}
{% for voter in record.voters %}
{% if user == voter %}
{% do disabled.append(1) %}
{% endif %}
{% endfor %}
{% if disabled %}
disabled
{% endif %}
вы можете использовать массив / dict, как предлагает Мигель, но вам не нужно расширение do как таковое; вы можете установить фиктивный var. Я использую следующее:
{% set glob={} %}
вверху, а затем в моем коде:
{% set _ = glob.update({'disabled':True}) %}
переменные _ - это просто манекен, вы не используете его впоследствии.
по умолчанию блоки не могут обращаться к переменным из внешних областей, вы можете переопределить это с помощью scoped
модификатор так:
{% for item in list scoped %}
{% endfor %}
см.:http://jinja.pocoo.org/docs/templates/#block-nesting-and-scope
Я понимаю, что отвечаю на старую тему. Однако недавно я начал использовать Jinja и столкнулся с аналогичной проблемой: мне нужно было подсчитать количество напечатанных строк во вложенных циклах. Мое решение заключалось в том, чтобы обернуть переменную счетчика в класс и передать экземпляр шаблону. Аналогично, вы можете использовать класс-оболочку, как так
class VoterStatus(object):
def __init__(self, status='active'):
self._status = status
def set_disabled(self):
self._status = 'disabled'
def __str__(self):
return self._status
измените свой шаблон соответствующим образом
{% for voter in record.voters %}
{% if user == voter %}
{% status.set_disabled() %}
{% endif %}
{{ status }} # outputs: 'disabled'
{% endfor %}
передать экземпляр класса состояния в шаблон для рендеринг:
tmplt.render(status=VoterStatus(), ...)
...а Боб - твой дядя.