Использование Jinja для фильтрации по вложенным значениям словаря - PullRequest
2 голосов
/ 01 апреля 2019

У меня есть следующий YAML в моем Столбе Соленого стека:

prometheus:
  services:
    cassandra:
      enabled: False
    cockroachdb:
      enabled: True
    haproxy:
      enabled: True
    swift:
      enabled: False

Я хочу иметь возможность перебирать список включенных служб.

{% for enabled_service_name in prometheus.services | selectattr('enabled') %}
{{ enabled_service_name }}
{% endfor %}

Однако это не работает, поскольку атрибут, который я пытаюсь отфильтровать, находится во вложенном словаре под именем службы:

{'cassandra': {'enabled': False},
 'cockroachdb': {'enabled': True},
 'haproxy': {'enabled': True},
 'swift': {'enabled': False}}

Очевидно, что я могу добиться того, чего хочу, применяя условный тест внутри цикла:

{% for name, properties in prometheus.services | dictsort %}
{% if properties.enabled %}
configuration for {{ name }}
{% endif %}
{% endfor %}

Однако я буду часто повторять этот список и предпочел бы, чтобы Джинджа применил встроенный фильтр в цикле for.

Есть ли способ фильтрации по значению элемента во вложенном словаре?

Ответы [ 2 ]

2 голосов
/ 07 апреля 2019

Что ж, я думаю, чем лучше структурирован файл yaml, тем больше вариантов у вас есть, чтобы решить эту проблему.

Я бы предложил следующую реструктуризацию:

prometheus:
  services:
    - name: cassandra
      enabled: False
    - name: cockroachdb
      enabled: True
    - name: haproxy
      enabled: True
    - name: swift
      enabled: False

Тогда выможет повторяться по-разному, это может быть одним из способов:
{{ prometheus.services | selectattr('enabled', True) | map(attribute='name') | list }}

Надеюсь, это поможет!

0 голосов
/ 28 мая 2019

Не изменяя структуру своего столпа, вы можете разделить свой список на две группы с помощью groupby.

{% for group in prometheus.services.items() | groupby ('1.enabled') %}
{% if group.grouper = True %}
{% set enabled_services = group.list %}
{% else %}
{% set disabled_services = group.list %}
{% endif %}
{% endfor %}

Это выглядит немного сложнее, но полезно, если вам нужно перебрать оба списка.

...