Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Templates 可以使用Jinja变量';s的范围是否扩展到内部块中?_Templates_Variables_Scope_Jinja2 - Fatal编程技术网

Templates 可以使用Jinja变量';s的范围是否扩展到内部块中?

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

我有以下Jinja模板:

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