jinja2 即使在使用 from_json 时也将列表转换为字符串

jinja2 turning lists into strings even when from_json is being used

我正在尝试 运行 嵌套 for 循环以检索嵌套值。 我想在 some_value_3 匹配预定义条件时检索 some_value_4

{
  "some_dict": {
    "some_key_0": "value_0",
    "some_key_1": "value_1"
  },
  "testval_dict": {
    "test_key_0": "some_value_0",
    "test_key_1": "some_value_1",
    "test_key_2": "some_value_2",
    "test_key_3": "some_value_3",
    "test_key_4": "some_value_4"
  }
}

剧本:

- hosts: localhost
  tasks:
   
   - set_fact:
       mydict: "{{ lookup('file', '/tmp/file.json' ) | from_json }}"

   - debug:
       msg: |
            "{% for item in mydict %}
             {{ item }}
             {% endfor %}"

当 运行 时,似乎字典名称被视为字符串,仅此而已:

ansible-playbook /tmp/test_playbook.yml -c local -i ', localhost'
TASK [debug] ******************************************************************
ok: [localhost] => {}

MSG:

" somee_dict
  testval_dict
 "

然后当我将 itme.key 添加到 debug 任务时,剧本失败:

MSG:

The task includes an option with an undefined variable. The error was: 'str object' has no attribute 'value'

谢谢。

编辑澄清 在真实的例子中,我不知道字典的名字,所以我不能使用 some_dicttestval_dict,这就是为什么我试图在 item.keyitem.value 形式。

如果需要循环字典,可以使用with_dict循环功能。这样,如果您遍历 mydict 并得到 item.key,您将得到 somee_dicttestval_dict.

  tasks:
  - set_fact:
      mydict: "{{ lookup('file', '/tmp/file.json')|from_json }}"
  # This will get the top level dictionaries somee_dict and testval_dict
  - debug:
      var: item.key
    with_dict: "{{ mydict }}"

如果您获得 mydictitem.value,您将获得子词典:

  - debug:
      var: item.value
    with_dict: "{{ mydict }}"

将产生(仅显示 testval_dict 的输出):

    "item.value": {
        "test_key_0": "some_value_0",
        "test_key_1": "some_value_1",
        "test_key_2": "some_value_2",
        "test_key_3": "some_value_3",
        "test_key_4": "some_value_4"
    }

问:"{% for item in mydict %} ...字典名称被视为字符串,仅此而已。"

答:这是正确的。字典,当评估为列表时,returns 其键的列表。请参阅下面的一些示例

    - debug:
        msg: "{{ mydict.keys()|list }}"
    - debug:
        msg: "{{ mydict[item] }}"
      loop: "{{ mydict.keys()|list }}"
    - debug:
        msg: "{{ mydict|difference(['testval_dict']) }}"

给予

  msg:
  - some_dict
  - testval_dict
  msg:
    some_key_0: value_0
    some_key_1: value_1

  msg:
    test_key_0: some_value_0
    test_key_1: some_value_1
    test_key_2: some_value_2
    test_key_3: some_value_3
    test_key_4: some_value_4
  msg:
  - some_dict

How to iterate through a list of dictionaries in Jinja template?