Jinja2: сравнение элементов в одном списке с элементами в другом списке

У меня есть список тем:

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

Я хотел бы проверить другой список по этому списку:

list2 = [topic2, topic4, topic6]

что-то вроде этого:

{% if list2.items in list1 %}

где каждый элемент из списка2 проверяется в списке1. если все или какие-либо элементы из list2 находятся в списке 1, то это 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 без доступа на стороне сервера, поэтому у меня есть только язык шаблонов для работы.


person JSum    schedule 07.11.2017    source источник
comment
Вы можете использовать понимание списка: [item for item in list1 if item in list2]   -  person ryugie    schedule 08.11.2017


Ответы (2)


Просто создайте собственный фильтр:

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

env.filters['intersect'] = intersect

А затем используйте его как любой другой фильтр:

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

Вот как это делается в Ansible .

person Max Malysh    schedule 07.11.2017

Мне неизвестны какие-либо встроенные тесты 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]))

Обратите внимание, что первый аргумент тестовой функции передается перед предложением is в шаблоне, а второй аргумент передается в квадратных скобках.

Это должно напечатать:

Is l1 in l2: yes

Узнайте, как определить пользовательские тесты здесь

person bow    schedule 07.11.2017
comment
Хорошие решения! Я использую cms, который дает мне только язык шаблонов для работы, поэтому я не могу работать со сценариями python. - person JSum; 08.11.2017
comment
Ах, в таком случае я не уверен, что вы можете использовать собственный фильтр Jinja2. Вероятно, вам придется перебирать элементы вручную в шаблоне. Однако это выглядело бы не так красиво, и логика шаблонов может зайти так далеко. - person bow; 08.11.2017