Templates 可以使用Jinja变量';s的范围是否扩展到内部块中?
我有以下Jinja模板:Templates 可以使用Jinja变量';s的范围是否扩展到内部块中?,templates,variables,scope,jinja2,Templates,Variables,Scope,Jinja2,我有以下Jinja模板: {% set mybool = False %} {% for thing in things %} <div class='indent1'> <ul> {% if current_user %} {% if current_user.username == thing['created_by']['username'] %} {% se
{% set mybool = False %}
{% for thing in things %}
<div class='indent1'>
<ul>
{% if current_user %}
{% if current_user.username == thing['created_by']['username'] %}
{% set mybool = True %}
<li>mybool: {{ mybool }}</li> <!-- prints True -->
<li><a href='#'>Edit</a></li>
{% endif %}
{% endif %}
<li>Flag</li>
</ul>
</div>
<hr />
{% endfor %}
{% if not mybool %}
<!-- always prints this -->
<p>mybool is false!</p>
{% else %}
<p>mybool is true!</p>
{% endif %}
{%set mybool=False%}
{%表示事物中的事物%}
{%if当前用户%}
{%if current_user.username==thing['created_by']['username']%}
{%set mybool=True%}
- mybool:{{mybool}}
{%endif%}
{%endif%}
- 旗
{%endfor%}
{%如果不是mybool%}
mybool是假的
{%else%}
mybool是真的
{%endif%}
如果在for
循环中满足条件,我想将mybool
更改为true,以便显示mybool is true代码>如下。但是,内部mybool
的范围似乎仅限于if
语句,因此从未设置所需的mybool
如何设置“全局”mybool
,以便在最后一个if
语句中使用它
编辑
我已经找到了(只有缓存的页面视图是正确的),但它们似乎不起作用。也许他们在金甲2被弃用了
编辑
下面提供了解决方案。我仍然很好奇为什么上面的建议不起作用。有谁确切地知道他们被弃用了吗 绕过此限制的一种方法是启用并使用数组而不是布尔值:
{% set exists = [] %}
{% for i in range(5) %}
{% if True %}
{% do exists.append(1) %}
{% endif %}
{% endfor %}
{% if exists %}
<!-- exists is true -->
{% endif %}
{%set exists=[]%}
{范围(5)%内的i的百分比}
{%if True%}
{%do存在。追加(1)%}
{%endif%}
{%endfor%}
{%如果存在%}
{%endif%}
要启用Jinja的“do”表达式语句扩展名:e=jinja2.Environment(扩展名=[“jinja2.ext.do”,])
在编写contextfunction()
或类似内容时,您可能已经注意到上下文试图阻止您修改它
如果您已经通过使用内部上下文API修改了上下文,那么您可能已经注意到上下文中的更改似乎在模板中不可见。原因是由于性能原因,Jinja
仅将上下文用作模板变量的主要数据源
如果要修改上下文,请编写一个返回变量的函数,而不是可以使用set指定给变量的函数:
{%set comments=get_latest_comments()%}
您可以使用此黑客解决您的问题(无扩展):
importjinja2
env=jinja2.Environment()
打印环境源字符串(“”)
{%set mybool=[False]}
{%表示事物中的事物%}
{%if当前用户%}
{%if current_user.username==thing['created_by']['username']%}
{%set}=mybool.append(不是mybool.pop())%}
- mybool:{{mybool[0]}}
{%endif%}
{%endif%}
- 旗
{%endfor%}
{%if不是mybool[0]}
mybool是假的
{%else%}
mybool是真的
{%endif%}
“”)。呈现(当前用户={'username':'me'},事物=[{'created_by':{'username':'me'}},{'created_by':{'username':'you'}])
回答一个相关问题:我想要一个全局计数器,记录我在模板中输入某个if块的次数,结果如下所示
在模板顶部:
{% set counter = ['1'] %}
在if块中,我要计算:
{% if counter.append('1') %}{% endif %}
显示计数时:
{{ counter|length }}
我相信字符串'1'
可以用任何字符串或数字替换。这仍然是一个黑客行为,但不是很大。需要从列表(objects\u from\u db)中查找对象(object)中的最大条目数
由于jinja2和variable scope中已知的原因,这不起作用
{% set maxlength = 0 %}
{% for object in objects_from_db %}
{% set ilen = object.entries | length %}
{% if maxlength < ilen %}
{% set maxlength = ilen %}
{% endif %}
{% endfor %}
{%set maxlength=0%}
{对象中的对象的%from_db%}
{%set-ilen=object.entries | length%}
{%if maxlength
以下是有效的方法:
{% set mlength = [0]%}
{% for object in objects_from_db %}
{% set ilen = object.entries | length %}
{% if mlength[0] < ilen %}
{% set _ = mlength.pop() %}
{% set _ = mlength.append(ilen)%}
{% endif %}
{% endfor %}
{% set maxlength = mlength[0] %}
{%set mlength=[0]}
{对象中的对象的%from_db%}
{%set-ilen=object.entries | length%}
{%if mllength[0]
希望这能帮助其他人找到同样的答案 2018年更新
自Jinja(2017年11月8日)起,有一个namespace()
对象来解决这个特殊问题。更多细节和示例见官方;然后,演示了如何为一个名称空间分配多个值。发现了这一伟大的发现,它描述了一个小技巧。无法在不同范围内更改jinja变量的值,但可以修改全局字典值:
# works because dictionary pointer cannot change, but entries can
{% set users = ['alice','bob','eve'] %}
{% set foundUser = { 'flag': False } %}
initial-check-on-global-foundUser:
cmd.run:
name: echo initial foundUser = {{foundUser.flag}}
{% for user in users %}
{%- if user == "bob" %}
{%- if foundUser.update({'flag':True}) %}{%- endif %}
{%- endif %}
echo-for-{{user}}:
cmd.run:
name: echo my name is {{user}}, has bob been found? {{foundUser.flag}}
{% endfor %}
final-check-on-global-foundUser:
cmd.run:
name: echo final foundUser = {{foundUser.flag}}
我还发现,这种语法非常有助于在不实际使用set
的情况下设置值:
{%- if foundUser.update({'flag':True}) %}{%- endif %}
它实际上检查字典上的更新操作的结果(请注意)。以下是希望使用名称空间()
对象使变量在for
循环之外持久化的一般情况
{% set accumulator = namespace(total=0) %}
{% for i in range(0,3) %}
{% set accumulator.total = i + accumulator.total %}
{{accumulator.total}}
{% endfor %}` {# 0 1 3 #}
{{accumulator.total}} {# 3 (accumulator.total persisted past the end of the loop) #}
这并不能回答您的问题,但您可以将mybool
设置为上下文变量,并将其传递到模板中。这是一个很好的想法,但不幸的是,它不起作用。一旦在模板中使用“set”,该变量的作用域就是局部变量。>下面提供的解决方案。我仍然很好奇为什么上面的建议不起作用。有谁确切地知道他们被弃用了吗?它们被删除是因为在生成的代码中无法正确预测它们在Python堆栈中的位置。这是可能的一些黑客,但它不值得的努力。将逻辑排除在模板之外:)不需要这个“do”表达式
{% set accumulator = namespace(total=0) %}
{% for i in range(0,3) %}
{% set accumulator.total = i + accumulator.total %}
{{accumulator.total}}
{% endfor %}` {# 0 1 3 #}
{{accumulator.total}} {# 3 (accumulator.total persisted past the end of the loop) #}