2012-02-28 13 views
44

ループ内でループ外で宣言された変数の値を変更したい。しかし、常に変化するので、ループの外側に初期値が保持されます。Jinja2:ループ内の変数の値を変更する

{% set foo = False %} 

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

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

これはレンダリング:

{% 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)! 

しかし、を

Ok(1)! 

だから、唯一の(悪い)ソリューションは、これまでだった発見しましたそれは非常に醜いです!別のより洗練されたソリューションがありますか?

+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でこれを行うPythonの方法がないことには非常に驚いています。 – kramer65

+0

特に、1つ以上の変数 –

+1

TLDRが必要な場合は、少し洗っています。 'set vars'はforループでうまく動作しませんか? – ThorSummoner

1

あなたは、これは以下の

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

そして中に一般化することができ、テンプレートコード

{% 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) 

をクリーンアップするためにこれを行うことができますサーバーコードの使用

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