Фильтрация данных из списка диктов по условию в фильтре Jinja2 - PullRequest
0 голосов
/ 20 ноября 2018
data:
  - { name: foo, app: foo, isweb: true }
  - { name: bar, app: bar, isweb: true }
  - { name: foobar, app: foobar, isweb: false }
  - { name: baz, app: baz, isweb: false }

Желаемый результат отображается в виде:

{% set  list= [] %}
{% for item in data %}
{% if item.isweb == true %}
{{list.append(item.app)}}
{% endif %}
{% endfor %}

Может ли это быть реализовано с использованием фильтров:

{{ data | map(attribute='app') | list | join(' ') }}

В основном вопрос заключается в том, как реализовать вышеприведенный цикл for, используя однострочный фильтр (как выше), но получать только те данные, которые имеют значение isweb true.

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Вы очень близки к решению, просто нужно добавить еще один фильтр:

{{ data | selectattr('isweb', 'equalto', true) | map(attribute='app') | list | join(' ') }}
0 голосов
/ 20 ноября 2018

Это можно сделать несколькими способами (работая с ansible 2.7. Не уверен в более низких версиях):

Путь чистого фильтра (с использованием selectattr и map):

- set_fact: app_list="{{ data | selectattr("isweb", "equalto", true) | map(attribute='app') | list }}"

Использование ansible loop с условием в фильтре:

- set_fact: app_list="{{ (app_list | default([])) + ([ item.app ] if (item.isweb == True) else []) }}"
  loop: "{{ data }}"

Использование Ansible loop с when оператором:

- set_fact: app_list="{{ (app_list | default([])) + [ item.app ] }}"
  loop: "{{ data }}"
  when: item.app is defined and item.app == true
...