You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jinja2嵌套字典值渲染异常:模板语法错误排查

Jinja2模板语法错误排查:接口IP/掩码无法输出

原模板

{%- 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 -%}

原JSON数据

{
  "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"
      }
  }
}

错误原因分析

  1. 多余内层循环导致无效遍历:devices.items()返回的是(设备键名, 设备数据字典)的元组,原模板中内层{% for data in device %}会遍历这个元组的两个元素——第一个是字符串类型的设备键(如d1),第二个才是真正的设备数据字典。遍历字符串时,data.hostname等属性会为空,同时打乱正常数据访问逻辑。
  2. 接口遍历未解构元组:data.interfaces.items()返回的是(接口名称, 接口数据字典)的元组,原模板直接用interface指代整个元组,尝试访问interface.ip等同于从元组中读取不存在的属性,自然返回空值。

修正后的模板

{%- for dev_key, dev_data in devices.items()  -%}
  {{ dev_data.hostname }}  {{ dev_data.routing_protocol }}
  {% for if_name, if_data in dev_data.interfaces.items() -%}
    {{ if_name }} {{ if_data.ip }} {{ if_data.mask }}
  {% endfor -%}
{% endfor -%}

输出效果

修正后会正确输出:

router-w-bgp  bgp
  Loopback0 10.0.0.1 32
  Loopback1 10.0.0.2 32
router-w-ospf  ospf
  Loopback0 10.0.0.2 32
router-w-defgw  default
  Ethernet1 10.10.0.10 24

内容的提问来源于stack exchange,提问作者ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:53:25