2013-07-29 3 views
6
{% set disabled = '' %} 
{% for voter in record.voters %} 
    {% if user == voter %} 
     {% set disabled = 'disabled' %} 
    {% endif %} 
    {{ disabled }} # outputs: 'disabled' 
{% endfor %} 
{{ disabled }} # outputs: '' 

У меня есть этот шаблон в Jinja2. Мне нужна переменная 'disabled', чтобы быть видимой вне цикла 'for'. Возможно ли это?Jinja2: локальная/глобальная переменная

ответ

10

Самый простой способ справиться с этим, чтобы переместить логика, которая устанавливает переменную disabled в функцию просмотра и отправляет ее в шаблон, готовый к использованию. Смешение логики приложения с презентацией - не очень хорошая идея, шаблоны должны получать данные как можно более усвоенные.

Это говорит о том, что есть уродливый взлом, который делает то, что вы хотите, показано в принятом ответе на this question.

Решение включает в себя расширение 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 %} 
+0

thx , Я уже пересмотрел свой код и сделал то, что вы предлагали вначале. –

0

По умолчанию блокирует не может получить доступ к переменным из внешних областей, вы можете изменить это с помощью модификатора scoped так:

{% for item in list scoped %} 
{% endfor %} 

См: http://jinja.pocoo.org/docs/templates/#block-nesting-and-scope

+1

Это не помогло! «Scoped» работает для блоков не для циклов –

+0

@ c00p3r.web. В этом случае я предлагаю открыть проблему для jinja2, поскольку это похоже на желаемую функциональность: https://github.com/mitsuhiko/jinja2/issues –

6

Вы можете использовать массив/Dict, как говорит Мигель, но вам не нужно расширение делать сам по себе ; вы можете установить фиктивный var. Я использую следующее:

{% set glob={} %} 

в верхней части, а затем в моем коде:

{% set _ = glob.update({'disabled':True}) %} 

В _ переменные просто манекен, не использовать его впоследствии.

0

Я понимаю, что я отвечаю на старую нить. Тем не менее, я начал использовать 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(), ...) 

... и Боб - твой дядя.

Смежные вопросы