2012-02-28 2 views
44

Я хочу изменить значение переменной, объявленной вне цикла в цикле. Но всегда меняя, он сохраняет начальное значение вне цикла.Jinja2: измените значение переменной внутри цикла

{% set foo = False %} 

{% for item in items %} 
    {% set foo = True %} 
    {% if foo %} Ok(1)! {% endif %} 
{% endfor %} 

{% if foo %} Ok(2)! {% endif %} 

Это делает:

Ok(1)! 

Так что единственное (плохо) решение было найдено до сих пор было так:

{% set foo = [] %} 

{% for item in items %} 
    {% if foo.append(True) %} {% endif %} 
    {% if foo %} Ok(1)! {% endif %} 
{% endfor %} 

{% if foo %} Ok(2)! {% endif %} 

Это делает:

Ok(1)! 
Ok(2)! 

Но, это очень уродливо! Есть ли еще более элегантное решение?

+3

Я не думаю, что есть какой-нибудь другой способ. Возможно, вы можете перестроить код, чтобы вам не нужно было устанавливать переменную. –

+0

+1 на вопрос, как он стал отвечать за меня :) –

+0

@Shankar Cabus: отличный вопрос. Это, вероятно, должно быть классифицировано под 'Jinja Annoyances' – dreftymac

ответ

47

Попробуйте также подход на основе словаря. Это кажется менее уродливым.

{% set vars = {'foo': False} %} 

{% for item in items %} 
    {% if vars.update({'foo': True}) %} {% endif %} 
    {% if vars.foo %} Ok(1)! {% endif %} 
{% endfor %} 

{% if vars.foo %} Ok(2)! {% endif %} 

Это также оказывает:

Ok(1)! 
Ok(2)! 
+2

Еще уродливый, но он работает. Я очень удивлен, что нет путинского способа сделать это с помощью jinja2. – kramer65

+0

Определенно немного чище, особенно если вам нужно больше одной переменной –

+1

TLDR, просто ли «set vars» не работает в цикле for? – ThorSummoner

1

Вы можете сделать это, чтобы очистить код шаблона

{% for item in items %} 
    {{ set_foo_is_true(local_vars) }} 
    {% if local_vars.foo %} Ok(1)! {% endif %} 
{% endfor %} 
{% if local_vars.foo %} Ok(2)! {% endif %} 

И в использовании кода сервера

items = ['item1', 'item2', 'item3'] 
#--------------------------------------------- 
local_vars = { 'foo': False } 
def set_foo_is_true(local_vars): 
    local_vars['foo'] = True 
    return '' 
env.globals['set_foo_is_true'] = set_foo_is_true  
#--------------------------------------------- 
return env.get_template('template.html').render(items=items, local_vars=local_vars) 

Это может быть обобщена следующим

{{ set_local_var(local_vars, "foo", False) }} 
{% for item in items %} 
    {{ set_local_var(local_vars, "foo", True) }} 
    {% if local_vars.foo %} Ok(1)! {% endif %} 
{% endfor %} 
{% if local_vars.foo %} Ok(2)! {% endif %} 

И код сервера используется

items = ['item1', 'item2', 'item3'] 
#--------------------------------------------- 
local_vars = { 'foo': False } 
def set_local_var(local_vars, name, value): 
    local_vars[name] = value 
    return '' 
env.globals['set_local_var'] = set_local_var 
#--------------------------------------------- 
return env.get_template('template.html').render(items=items, local_vars=local_vars) 
4

, как указано в документации:

Пожалуйста, обратите внимание, что задания в петлях будут удалены в конце итерации и не может пережить .

, но в версии 2.10 вы можете использовать пространство имен:

{% set ns = namespace(foo=false) %}  
    {% for item in items %} 
     {% set ns.foo = True %} 
     {% if ns.foo %} Ok(1)! {% endif %} 
    {% endfor %} 

    {% if ns.foo %} Ok(2)! {% endif %} 
Смежные вопросы