如何使用Jinja2将静态项目附加到字典

时间:2019-04-18 14:37:45

标签: python python-3.x ansible jinja2

如果我有以下列表:

[
    {
        "a": "1",
        "b": "2"
    },
    {
        "a": "3",
        "b": "4"
    },
    {
        "a": "5",
        "b": "6"
    }            
]

如何重命名第一个列表的键,并使用Jijja2过滤器将静态项附加到每个字典?

例如:

[
    {
        "a2": "1",
        "b2": "2",
        "c2": "test"
    },
    {
        "a2": "3",
        "b2": "4",
        "c2": "test"
    },
    {
        "a2": "5",
        "b2": "6"
        "c2": "test"
    }            
]

我尝试了以下操作:

{{ my_list | map('json_query', '{a2:a, b2:b}') | list }}

这是成功的一半,但是我该如何在结果字典中添加静态项目呢?

2 个答案:

答案 0 :(得分:1)

以下应做:

- debug:
  msg: >-
    {{ my_list | json_query("[].{a2: a, b2: b, c2: 'test' }") }}

复制数据后的结果:

    "msg": [
        {
            "a2": "1",
            "b2": "2",
            "c2": "test"
        },
        {
            "a2": "3",
            "b2": "4",
            "c2": "test"
        },
        {
            "a2": "5",
            "b2": "6",
            "c2": "test"
        }
    ]
}

单引号和双引号嵌套的顺序(请参见jmespath specification)。如果将单引号/双引号放在另一边,则静态字符串的结果将为"None"

答案 1 :(得分:0)

我将定义一个全局python函数来更改字典。看起来像:

def some_func(my_sequence):
    new_sequence = []
    for my_dict in my_sequence:
        new_dict = {f"{key}2": value for key, value in my_dict.items()}
        new_dict.update(c2="test")
        new_sequence.append(new_dict)
    return new_sequence

当然可以进行改进以删除硬编码。

一旦定义了Jinja2环境,我将声明一个指向该函数的自定义过滤器。

environment.filters["my_customfilter"] = some_func

并按如下所示将其用于模板:

{{ my_list|my_customfilter() }}

或进入循环:

{% for my_dict in my_list|my_customfilter() %}
    {# do something here #}
{% endfor %}

或任何其他用途。

这样,主要的逻辑不是由Jinja2(它只是一个模板引擎)带来的,而是由您的主要python脚本带来的。您的代码在进化的情况下更加灵活。