繁体   English   中英

访问 Jinja2 中 3 层字典的值

[英]Accessing values of dictionary 3 levels deep in Jinja2

我在 somefile.jinja2 文件中定义了一个字典:


{%
   set virtual_servers = {
    'pc_k8snode': {
          'server1': {
              'name': 'server001',
              'ip_address': '10.10.10.10',
          },
          'server2': {
              'name': 'server002',
              'ip_address': '20.20.20.20',
          },
          'server_state': 'ENABLED',
          'service_protocol': 'HTTP',
          'service_port': '80',
          'cs_ip_address': '30.30.30.30',
          'cs_port': '443',
    },
  },
%}

我有另一个名为 template.jinja2 的 jinja2 文件,它导入了 somefile.jinja2:

{%- import somefile.jinja2' as device -%}

{% for vs in device.virtual_servers %}
    {% for servers in vs %}
        {% for srv in vs[servers] %}
add server {{ srv }}
        {% endfor %}
    {% endfor %}
{% endfor %}

它目前打印出:

add server server1
add server server2
add server server_state
add server service_protocol
add server service_port
add server cs_ip_address
add server cs_port

server1 和 server2 有 3 层深。 我想打印出以下 output:

add server server001 10.10.10.10
add server server002 20.20.20.20

您可以使用vs[servers][srv]["name"]vs[servers][srv]["ip_address"]

您还可以将这些值与if一起使用,以在显示其他值时跳过nameip_address

{%- import 'somefile.jinja2' as device -%}

{%- for vs in device.virtual_servers %}
    {%- for servers in vs -%}
        {%- for srv in vs[servers] -%}
{%- if vs[servers][srv]["name"] %}        
add server {{ vs[servers][srv]["name"] }} {{ vs[servers][srv]["ip_address"] }}
{%- else %}
add server {{ srv }} {{ vs[servers][srv] }}
{%- endif %}
        {%- endfor %}
    {%- endfor %}
{%- endfor -%}

结果:

add server server001 10.10.10.10        
add server server002 20.20.20.20
add server server_state ENABLED
add server service_protocol HTTP
add server service_port 80
add server cs_ip_address 30.30.30.30
add server cs_port 443

顺便提一句:

jinja中,您还可以使用.items().values().keys()

{%- for server in vs.values() -%}
{%- for key, val in server.items() -%}

在你的模板中它可能是

{%- import 'somefile.jinja2' as device -%}

{%- for vs in device.virtual_servers %}
    {%- for server in vs.values() -%}
        {%- for key, val in server.items() -%}
{%- if val["name"] %}        
add server {{ val["name"] }} {{ val["ip_address"] }}
{%- else %}
add server {{ key }} {{ val }}
{%- endif %}
        {%- endfor %}
    {%- endfor %}
{%- endfor -%}

如果您只需要服务器,则跳过else

{%- import 'somefile.jinja2' as device -%}

{%- for vs in device.virtual_servers %}
    {%- for server in vs.values() -%}
        {%- for key, val in server.items() -%}
{%- if val["name"] %}        
add server {{ val["name"] }} {{ val["ip_address"] }}
{%- endif %}
        {%- endfor %}
    {%- endfor %}
{%- endfor -%}

或者你应该保持server1server2作为子词典即。 "servers": {"server1": ... , "server2": ...}并且只使用device.virtual_servers["servers"]

您还可以在子词典中保留其他值,即"options"{ {"server_state": ..., "service_protocol": ..., ...}然后只显示选项可能更简单,因为您只能使用device.virtual_servers["options"]

{%
   set virtual_servers = {
    'pc_k8snode': {
    
          'servers': {
              'server1': {
                  'name': 'server001',
                  'ip_address': '10.10.10.10',
              },
              'server2': {
                  'name': 'server002',
                  'ip_address': '20.20.20.20',
              },
          }, 
          
          'options': {
              'server_state': 'ENABLED',
              'service_protocol': 'HTTP',
              'service_port': '80',
              'cs_ip_address': '30.30.30.30',
              'cs_port': '443',
          }
    }
  }
%}

编辑:

我用来呈现模板的代码

主程序

from jinja2 import Environment, PackageLoader, select_autoescape

env = Environment(
    loader=PackageLoader("main"),  # I run `main.py` so it should use `main`
    autoescape=select_autoescape()
)

template = env.get_template("main.jinja2")

print(template.render())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM