Jinja2:将一个列表中的项与另一个列表中的项进行比较

3

我有一个话题列表:

list1 = [topic1, topic2, topic3, topic4, topic5, topic6]

我想要将另一个列表与此列表进行比对:
list2 = [topic2, topic4, topic6]

类似这样的内容:

{% if list2.items in list1 %}

在此处,需要检查list2中的每个项是否在list1中。如果list2中的任何一项或所有项都在list1中,则返回True。我觉得这很简单,但是我似乎找不到有用的信息。

完整示例:

{% set list1 = [topic2, topic4, topic6] %}

{% for post in posts %}

   {% set list2 = [topic1, topic2, topic3, topic4, topic5, topic6] %}

   {% for topic in list2 %}
       {% if topic in list1 %}

          {# output of post list based on conditions #}

       {% endif %}
   {% endfor %}
{% endfor %}

** 我正在使用没有服务器端访问权限的cms,因此我只能使用模板语言进行工作。


1
你可以使用列表推导式:[item for item in list1 if item in list2] - ryugie
2个回答

9

只需创建一个自定义过滤器:

def intersect(a, b):
    return set(a).intersection(b)

env.filters['intersect'] = intersect

然后像使用其他过滤器一样使用它:

    {% if list1 | intersect(list2) %}
        hello
    {% else %}
        world
    {% endif%} 

这就是在Ansible中的做法。

1

我不知道任何可以做到这一点的 Jinja2内置测试,但是添加你自己的测试非常容易。

假设您有一个模板,如下所示,在名为template.j2的文件中:

Is l1 in l2: {% if l1 is subsetof(l2) %}yes{% else %}no{% endif %}

你可以在同一目录下编写一个Python脚本,添加以下检查代码:
import jinja2


def subsetof(s1, s2):
    return set(s1).issubset(set(s2))


loader = jinja2.FileSystemLoader(".")
env = jinja2.Environment(loader=loader)
env.tests["subsetof"] = subsetof

template = env.get_template("template.j2")
print(template.render(l1=[1, 2], l2=[1, 2, 3]))

注意test函数的第一个参数在模板中的is子句之前传递,而第二个参数是在括号内传递的。
这应该打印出:
Is l1 in l2: yes

请看如何定义自定义测试此处


很棒的解决方案!不过我正在使用一个只提供模板语言的CMS,所以无法使用Python脚本。 - JSum
啊,这种情况下,我不确定您是否可以使用自定义的Jinja2过滤器。您可能需要在模板中手动迭代项目。这样看起来可能不太好,而且模板逻辑也只能到达一定程度。 - bow

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