Jinja 变量的范围可以扩展到内部块之外吗?
我有以下 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 %}
如果 for
循环中满足条件,我想将 mybool
更改为 true,以便我可以显示 mybool is true !
下面。但是,内部 mybool
的范围似乎仅限于 if
语句,因此期望的 mybool
从未设置。
如何设置“全局”mybool
以便我可以在最后一个 if
语句中使用它?
编辑
我发现一些建议(仅正确缓存的页面视图),但它们似乎没有工作。也许它们在 Jinja2 中已被弃用...
下面提供了编辑
解决方案。我仍然很好奇为什么上面的建议不起作用。有谁确切知道它们已被弃用?
I have the following Jinja template:
{% 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 %}
If the condition is met in the for
loop, I'd like to change mybool
to true so I can display mybool is true!
below. However, it looks like the scope of the inner mybool
is limited to the if
statement, so the desired mybool
is never set.
How can I set the "global" mybool
so I can use it in the last if
statement?
EDIT
I've found some suggestions (only the cached page views correctly), but they don't seem to work. Perhaps they're deprecated in Jinja2...
EDIT
Solution provided below. I am still curious why the suggestions above do not work though. Does anyone know for sure that they were deprecated?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
解决此限制的一种方法是启用 "do" 表达式语句扩展 并改用数组of boolean:
启用 Jinja 的“do”表达式语句扩展:
e = jinja2.Environment(extensions=["jinja2.ext.do",])
One way around this limitation is to enable the "do" expression-statement extension and use an array instead of boolean:
To enable Jinja's "do" expression-statement extension:
e = jinja2.Environment(extensions=["jinja2.ext.do",])
对于想要使用
namespace()
对象让变量在for
循环之外保留的人来说,这是一般情况。Here's the general case for anyone wanting to use the
namespace()
object to have a variable persist outside of afor
loop.回答相关问题:我想要一个全局计数器,记录我在模板中输入某个 if 块的次数,结果如下。
在模板的顶部:
在 if 块中我想计数:
显示计数时:
我相信字符串
'1'
可以替换为任何字符串或数字。它仍然是一个黑客,但不是一个很大的黑客。Answer to a related question: I wanted to have a global counter of the number of times I entered a certain if-block in the template, and ended up with the below.
At the top of the template:
In the if-block I want to count:
When displaying the count:
The string
'1'
can be replaced with any string or digit, I believe. It is still a hack, but not a very large one.2018 年更新
自 Jinja 2.10 起(2017 年 11 月 8 日)有一个
namespace()
对象可以解决这个特定问题。有关更多详细信息,请参阅官方作业文档一个例子;class
文档然后说明了如何分配多个命名空间的值。Update 2018
As of Jinja 2.10 (8th Nov 2017) there is a
namespace()
object to address this particular problem. See the official Assignments documentation for more details and an example; theclass
documentation then illustrates how to assign several values to a namespace.您可以使用此技巧解决您的问题(无需扩展):
You can solve your problem using this hack (without extensions):
当编写
contextfunction()
或类似的东西时,您可能已经注意到上下文试图阻止您修改它。如果您已设法使用内部上下文 API 修改上下文,您可能会注意到上下文中的更改在模板中似乎不可见。原因是出于性能原因,
Jinja
仅使用上下文作为模板变量的主要数据源。如果要修改上下文,请编写一个返回变量的函数,而不是可以使用 set 分配给变量:
{% set comments = get_latest_comments() %}
来源
When writing a
contextfunction()
or something similar you may have noticed that the context tries to stop you from modifying it.If you have managed to modify the context by using an internal context API you may have noticed that changes in the context don’t seem to be visible in the template. The reason for this is that
Jinja
uses the context only as primary data source for template variables for performance reasons.If you want to modify the context write a function that returns a variable instead that one can assign to a variable by using set:
{% set comments = get_latest_comments() %}
Source
需要从列表(objects_from_db)中查找对象(object)中的最大条目数,
由于 jinja2 和变量范围中已知的原因,这不起作用。
这是有效的:
希望这可以帮助其他试图弄清楚同样问题的人。
Had a need to find the max num of entries in an object (object) from a list (objects_from_db),
This did not work for reasons known in jinja2 and variable scope.
Here's what works:
Hope this helps someone else trying to figure out the same.
发现这个很棒的 文章 描述了一个小技巧。不可能在不同的范围内更改 jinja 变量的值,但可以修改全局字典值:
我还发现这种语法非常有用,可以在不实际使用
set
的情况下设置值:它实际上检查字典上更新操作的结果(自我注释)。
Found this great article that describes a little hack. It's not possible to change value of a jinja variable in a different scope, but it's possible to modify a global dictionary values:
I've also found very helpful this syntax to set the value without actually using
set
:It actually checks the result of an
update
operation on a dictionary (note to self).