Search code examples
jinja2

Jinja2 not rendering values properly in nested dictionaries


Given the Jinja2 template:

{%- for device in devices.items()  -%}
   {%- for data in device -%}
      {{ data.hostname }}  {{ data.routing_protocol }}
      {% for interface in data.interfaces.items() -%}
         {{ interface }} {{ interface.ip }} {{ interface.mask }}
      {% endfor -%}
   {% endfor -%}
{% endfor -%}

and the JSON data:

{
  "devices":{
    "d1":{
        "hostname":"router-w-bgp",
        "routing_protocol":"bgp",
        "interfaces":{
          "Loopback0":{"ip":"10.0.0.1","mask":32},
          "Loopback1":{"ip":"10.0.0.2","mask":32}
        },
        "bgp":{"as":65001}
      },
    "d2":{
        "hostname":"router-w-ospf",
        "routing_protocol":"ospf",
        "interfaces":{
          "Loopback0":{"ip":"10.0.0.2","mask":32}
        },
        "ospf":{"pid":1}
      },
    "d3":{
        "hostname":"router-w-defgw",
        "routing_protocol":"default",
        "interfaces":{
          "Ethernet1":{"ip":"10.10.0.10","mask":24}
        },
        "default_nh":"10.10.0.1"
      }
  }
}

The problem is the template can't print the value of {{ interface.ip }} {{ interface.mask }} they are blank. So, where is the wrong part in my Jinja2 syntax?

I tried many times to modify the Jinja2 template but always either gets errors or blank values. I'm using online website for testing. No python needed in my case.


Solution

  • When doing a loop for ... in dict.items() you end up with a tuple (key, value), which you should unpack in the loop you want to use them:

    {% for key, value in dict.items() %}
    {% endfor %}
    

    So, in your case:

    {%- for device_name, device in devices.items()  -%}
      {{ device.hostname }}  {{ device.routing_protocol }}
      {% for interface_name, interface in device.interfaces.items() -%}
        {{ interface_name }} {{ interface.ip }} {{ interface.mask }}
      {% endfor -%}
    {% endfor -%}