【问题标题】:Jinja2 If ignores boolean valueJinja2 If 忽略布尔值
【发布时间】:2019-03-22 09:07:12
【问题描述】:

我有一个 Jinja2 模板,其中解析为布尔值 False 的变量在 {% if %} 语句中被忽略。

模板的相关块看起来像

{% if user.can_manage_techniques %}j
{% block submenu_items %}
<li class="pure-menu-item"><a href={{ url_for('new_technique') }} class="pure-menu-link">New Technique</a></li>
{% endblock %}
{% endif %}

用户在渲染模板中设置为

    return render_template('technique_list.j2',
                            techniques=Technique.find_all(),
                            **state())

state 是一个返回 dict[string, object] 的函数。

传递给它的用户在对象的__init__ 中设置为变量 - 所以:

    def __init__(self):
        self.can_manage_techniques = False

即使can_manage_techniques 为假,列表项仍会呈现。如何让{% if %} 意识到它是错误的并转到{% endif %}

我也试过== truesameas true

【问题讨论】:

  • 如果您尝试显示 `user.can_manage_techniques` 会发生什么?
  • 如果我使用 {{ user.can_manage_techniques }} Jinja2 将其填写为“False”(不带引号)
  • 我这边无法复制...

标签: python flask jinja2


【解决方案1】:

我无法使用以下最小应用在本地重现您的问题:

from flask import Flask, render_template_string
app = Flask(__name__)

@app.route('/')
def hello():
    return render_template_string('''
        {{ can }}
        {% if can %}
            {% block submenu_items %}
                <li class="pure-menu-item">New Technique</li>
            {% endblock %}
        {% endif %}
        ''', can=False)

IMO,用法是正确的,所以你可能需要检查更多的相关代码。

在查看您在 GitHub 上的代码后,我找到了发生这种情况的原因。模板继承行为导致的这个问题:在子模板中,块外的内容会被跳过

由于你的模板是子模板,所以你需要将 if 语句放入块中。

【讨论】:

  • 相关代码:我觉得跟模板和块有关系。根据我的回答找到了解决方法。
【解决方案2】:

如果{% if %} 语句在块之外 - 它被忽略。如果它在块内,则成功。我不知道为什么 - 但这是解决方法:

{% block submenu_items %}
{% if user.can_manage_techniques == true %}
<li class="pure-menu-item"><a href={{ url_for('new_technique') }} class="pure-menu-link">New Technique</a></li>
{% endif %}
{% endblock %

【讨论】:

【解决方案3】:

我相信这可能是您定义TrueFalse 的方式,在python 中它们应该是布尔类型(您可以使用type(test) 进行测试)。这些不应该是字符串或其他东西。它总是返回 true 的原因可能是因为非空字符串评估为 true(例如,Bool('false')True,而 Bool('')False)。

from jinja2 import Template

template = Template(
    """{% if test %}
{% block submenu_items %}
My Stuff
{% endblock %}
{% endif %}
""")

如果我运行以下任一命令,我会得到预期的结果:

template.render(test=False)
template.render(test=True)

【讨论】:

  • 我可以验证 type(state()['user'].can_manage_techniques) 是一个布尔值。我还手动添加了 can_manage_techniques=False,并将其更改为 just if can_manage_techniques(和 if_can_manage_techniques == true),并且在这两种情况下,仍然显示块
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-21
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多