【问题标题】:How can I break a for loop in jinja2?如何打破 jinja2 中的 for 循环?
【发布时间】:2014-04-04 17:00:00
【问题描述】:

如何在 jinja2 中跳出 for 循环?

我的代码是这样的:

<a href="#">
{% for page in pages if page.tags['foo'] == bar %}
{{page.title}}
{% break %}
{% endfor %}
</a>

我有不止一个页面具有此条件,我想在满足条件后结束循环。

【问题讨论】:

标签: python for-loop jinja2


【解决方案1】:

您不能使用break,而是要进行过滤。来自 Jinja2documentation on {% for %}

与 Python 不同,它不可能在循环中中断或继续。但是,您可以在迭代期间过滤序列,从而允许您跳过项目。以下示例跳过所有隐藏的用户:

{% for user in users if not user.hidden %}
    <li>{{ user.username|e }}</li>
{% endfor %}

但是,在您的情况下,您似乎只需要 first 元素;只需过滤并选择第一个:

{{ (pages|selectattr('tags.foo', 'eq', bar)|first).title }}

这使用selectattr() filter 过滤列表,其结果将传递给first filter

selectattr() 过滤器生成一个迭代器,因此在此处使用first 只会迭代输入直到第一个匹配元素,而不会进一步。

【讨论】:

  • 这并不总是一个好方法。例如,我有一个案例,其中有一个类从其他地方提取数据并根据请求(通过迭代器)传递它。如果我只想显示前 25 个元素,那么强制我的代码遍历所有元素,例如 500 个元素,然后将它们从显示中过滤掉是非常低效的。
  • @Canuck:您可以自行决定是否为模板提供更小的数据集。
  • @Canuck:另一方面,|first 过滤器将确保不会迭代整个数据集; selectattr() 使用迭代,它不会产生一个全新的列表,所以first 只需要迭代直到第一个匹配元素
  • @Canuck:我不确定这是否值得反对;您的情况与此处问题中的情况完全不同。如果您有一个大型数据集并且您只需要前 25 个元素,则要么使用模板限制该数据集的任何调用,要么尝试使用 slice() 并仅使用第一批。
  • 这个在 Django 中不起作用???至少在我的情况下,它抱怨 for 格式应该是 for x in y only
【解决方案2】:

但是如果你出于某种原因需要一个循环,你可以使用“loop.first”检查for循环块内的循环索引:

{% for dict in list_of_dict %} 
    {% for key, value in dict.items() if loop.first %}
      <th>{{ key }}</th>
    {% endfor %} 
{% endfor %}

【讨论】:

  • 头疼,但它与“loop.first”一起工作,谢谢!
【解决方案3】:

BreakContinue 可以使用循环控制扩展添加到 Jinja2。 Jinja Loop Control 只需将扩展添加到 jinja 环境。

jinja_env = Environment(extensions=['jinja2.ext.loopcontrols'])

根据sb32134 comment

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    相关资源
    最近更新 更多