Jinja2:本地/全局变量

c00*_*web 7 jinja2 flask

{% set disabled = '' %}
{% for voter in record.voters %}
    {% if user == voter %}
        {% set disabled = 'disabled' %}
    {% endif %}
    {{ disabled }}  # outputs: 'disabled'
{% endfor %}
{{ disabled }}  # outputs: ''
Run Code Online (Sandbox Code Playgroud)

我在Jinja2中有这个模板.我需要的是'禁用'变量,以便在'for'循环之外可见.那可能吗?

Mig*_*uel 12

处理此问题的最简单方法是移动将disabled变量设置为视图函数的逻辑,并将其发送到准备使用的模板.将应用程序逻辑与表示混合不是一个好主意,模板应该尽可能地接收数据.

也就是说,有一个丑陋的黑客可以使你想要的东西成为可能,在这个问题的公认答案中显示出来.

该解决方案涉及启用doJinja2 的扩展并使用它来修改全局数组.要启用扩展程序,请使用:

app.jinja_env.add_extension('jinja2.ext.do')
Run Code Online (Sandbox Code Playgroud)

以下是适用于您的示例的解决方案:

{% set disabled = [] %}
{% for voter in record.voters %}
    {% if user == voter %}
        {% do disabled.append(1) %}
    {% endif %}
{% endfor %}
{% if disabled %}
    disabled
{% endif %}
Run Code Online (Sandbox Code Playgroud)


小智 10

你可以像Miguel建议的那样使用数组/字典,但你本身并不需要do扩展; 你可以设置一个虚拟变量.我使用以下内容:

{% set glob={} %}
Run Code Online (Sandbox Code Playgroud)

在顶部,然后在我的代码中:

{% set _ = glob.update({'disabled':True}) %}
Run Code Online (Sandbox Code Playgroud)

_变量只是一个虚拟变量,之后不再使用它.


mob*_*bin 7

从版本 2.10 开始,可以使用允许跨范围传播更改的命名空间对象来处理更复杂的用例:

{% set ns = namespace(found=false) %}
{% for item in items %}
    {% if item.check_something() %}
        {% set ns.found = true %}
    {% endif %}
    * {{ item.title }}
{% endfor %}
Found item having something: {{ ns.found }}
Run Code Online (Sandbox Code Playgroud)