如何在jinja2中跳出for循环?

60

我该如何在jinja2中跳出for循环?

我的代码如下:

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

我有不止一页符合这个条件,我想一旦满足条件就结束循环。


12
有相关的扩展程序:extensions/#loop-controls - sb32134
3个回答

76

根据 Jinja2 {% for %} 文档,你不能使用 break,你需要使用过滤器来跳过元素:

不同于 Python,在循环中无法使用 breakcontinue。但你可以在迭代时通过过滤器过滤序列以跳过特定的元素。下面的示例演示了如何跳过所有隐藏的用户:

{% for user in users if not user.hidden %}
    <li>{{ user.username|e }}</li>
{% endfor %}
在您的情况下,似乎只需要第一个元素;只需筛选并选择第一个即可。
{{ (pages|selectattr('tags.foo', 'eq', bar)|first).title }}

这里使用selectattr()筛选器来过滤列表,然后将结果传递给first筛选器

selectattr()筛选器会产生一个迭代器,因此在这里使用first仅会迭代到第一个匹配元素,并停止迭代。


1
这并不总是一个好的方法。例如,我有一个情况,其中有一个类从其他地方提取数据,并在请求时通过迭代器传递它。如果我只想显示前25个元素,强制我的代码遍历所有500个元素并仅从显示中过滤它们是非常低效的。 - Canuck
1
@Canuck:接下来就看你的想法了,你可以使用较小的数据集来提供模板。 - Martijn Pieters
3
与之相反,|first 过滤器将确保不会遍历整个数据集;selectattr() 使用迭代,它不会生成一个全新的列表,因此 first 仅需要迭代直到找到第一个匹配元素 - Martijn Pieters
1
@Canuck:我不确定这个回答是否应该被踩,因为你的情况与这里的问题非常不同。如果你有一个大数据集,只需要前25个元素,要么让调用模板的程序限制数据集的大小,要么尝试使用slice()函数并仅使用第一批数据。 - Martijn Pieters
这个在Django中不起作用吗???至少在我的情况下,它抱怨for格式应该只是for x in y - holms
显示剩余3条评论

25

BreakContinue 可以通过循环控制扩展添加到 Jinja2 中。 Jinja 循环控制 只需将扩展添加到 Jinja 环境即可。

jinja_env = Environment(extensions=['jinja2.ext.loopcontrols'])
根据 sb32134 的评论

13

但是如果由于某些原因你需要循环,你可以使用 "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" 成功了。谢谢! - rulisastra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接