2012-02-28 459 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

,我不認爲有任何其他方式。也許你可以重構代碼,這樣你就不需要設置變量。 – 2012-02-28 17:25:45

+0

+1的問題,因爲它成爲了我的答案:) – 2013-10-17 15:05:58

+0

@Shankar Cabus:很好的問題。這應該可能被歸類在'金嘉煩惱' – dreftymac 2015-09-14 16:19:28

回答

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

仍然醜陋,但它的作品。我很驚訝沒有Pythonic與jinja2這樣做的方式。 – kramer65 2015-12-03 09:15:46

+0

肯定有點清潔,特別是如果你需要多個變量 – 2016-07-20 20:16:35

+1

TLDR,'set vars'只是普通的不能在for循環中工作嗎? – ThorSummoner 2017-02-15 21:10:46

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 %}