首页 > 解决方案 > 如何删除 jinja 嵌套循环中的最后一项?

问题描述

使用单个循环,很容易编写从循环的最后一次迭代中{% if not loop.last %}JOIN{% endif %}删除。JOIN

使用嵌套循环,我们可以访问外部循环,允许我们检查我们是否处于两个循环的最终迭代中。

不过,我有一个 3 级嵌套,对此解决方案非常冗长:

{% set loop1 = loop %}
...
{% set loop2 = loop %}
...
{% if not loop1.last and loop2.last and loop.last %}JOIN{% endif %}

有没有更好的方法来跳过嵌套循环的最后一次迭代?

标签: pythonjinja2

解决方案


如果您愿意编写一点 Python,您可以通过编写自定义过滤器(此代码必须在加载任何模板之前运行)或仅添加all到全局 Jinja2 环境来使其成为一个干净的内衬:

from jinja2 import Environment, PackageLoader, select_autoescape, last

env = Environment(
    loader = PackageLoader('yourapplication', 'templates'),
    autoescape = select_autoescape(['html', 'xml'])
)

def between(token, *args):
    return token if all(x.last for x in args) else ''

env.globals['between'] = between
env.globals['all'] = all

现在你可以这样做:

{{ 'JOIN'|between(loop1, loop2, loop) }}
# or
{% if not all([loop1, loop2, loop]|map('last')) %}JOIN{% endif %}

否则,您可以实现一个 Jinja2,该宏使用特殊varargs变量来访问作为 Jinja2 列表传递给宏的所有未命名参数。

{% macro between(token) -%}
    {% if not varargs|map('last')|select|length == varargs|length -%}
        {{ token }}
    {%- endif %}
{%- endmacro %}

请注意,-示例中的使用表示宏展开时将删除{%-前后的空格。-%}现在的用法:

{{ between(token = JOIN, loop1, loop2, loop) }}

您可以将各种 Jinja2 实用程序宏保存在一个文件中,并将其包含在模板的顶部,如下所示:{% include 'util.jinja2' as 'util' %}并且用法变为:

{{ util.between(token = JOIN, loop1, loop2, loop) }}

制作宏集合并在模板中使用它的另一种方法是在模板中内联。这是一个单一的班轮做这个伎俩的想法:

{% set loops = [loop1, loop2, loop] %}
{% if not loops|map('last')|select|length == loops|length %}JOIN{% endif %}

推荐阅读