【问题标题】:Issue creating a variable name dynamically from jinja2 for loop问题从 jinja2 for 循环动态创建变量名
【发布时间】:2021-04-06 11:31:41
【问题描述】:

我正在尝试创建一组模板,其名称及其内容基于某些列表和字典动态创建。

导致问题的部分代码如下。

{% for tenant in object_list %}
{%- set name = 'object_t' + tenant + 'rules' %}
{{name}}:
    - permit ip any {{ tenant_public_ip['object_t' + tenant | string +'_pub'['Subnets'][0] }}
{% endfor %}

# combine acls
complete_acls:
  - name: DEFAULT_ACL
    rules: {{'"{{ default_rules }}"'}}

  {% for tenant in object_list %}
  {% set item= 'object_t' + tenant + 'rules' %}
  - name: Tenant_{{tenant}}_ACCESS-VLANS
    rules: {{"{{item}}"}}
  {% endfor %} 

出现错误:模板化字符串时出现模板错误:预期标记 ',',得到 '{'。

正在解析的参数:

object_list: [1, 2, 3, 4, 5]
 
tenant_public_ip: {u''object_t5_pub'': {u''Subnets'': [u''8.51.14.124/28''], u''Vlan_id'': u''5010''}, u''object_t2_pub'': {u''Subnets'': [u''8.51.14.128/28''], u''Vlan_id'': u''2010''}, u''object_t4_pub'': {u''Subnets'': [u''8.51.14.176/28''], u''Vlan_id'': u''4100''}, u''object_t1_pub'': {u''Subnets'': [u''8.51.14.160/28''], u''Vlan_id'': u''1100''}, u''object_t3_pub'': {u''Subnets'': [u''8.51.14.144/28''], u''Vlan_id'': u''3100''}} '

我是 Jinja2 模板的新手,我做错了什么?

在最初的问题之后我遇到的另一个问题是在添加了上面的几个模块后组合底部的所有规则时。

我将规则作为“项目”变量名称拆分为字母 - “o、b、j、e、c、t”,而不是收集之前创建的存储在“object_t_1rules”下的规则。我可以通过直接使用创建它们的特定名称来单独访问它们,但不使用 for 循环。我知道 Jinja2 不允许嵌套变量访问。我还能如何在这里实现我想要的?

【问题讨论】:

  • 感谢编辑
  • 顺便说一句,你应该在 StackOverflow 中隐藏你的 IP...
  • 谢谢,但那些都是假的。
  • 哦,完美!祝你的项目好运:)
  • 我不确定我是否理解您的编辑,但是,我可以参考您一些很棒的文档来源:this in-depth documentthis webpage

标签: python jinja2 templating


【解决方案1】:

您的模板/代码中有多个错误,准确地说是以下几行:

{%- set name = 'object_t' + tenant + 'rules' %}
  - permit ip any {{ tenant_public_ip[ip_{{tenant}}_pub][Subnets][0] }}

首先,tenant 是一个整数,您试图将它放在两个字符串之间。 Jinja 比普通 Python 更宽容,所以你需要一个过滤器:

{%- set name = 'object_t' + tenant | string + 'rules' %}

其次,Subnets 应该是一个字符串;但是,您正在尝试访问一个名为 Subnets 的对象(因为缺少撇号):

  - permit ip any {{ tenant_public_ip[ip_{{tenant}}_pub]['Subnets'][0] }}

第三,您不需要包裹在tenant 周围的{{}}

  - permit ip any {{ tenant_public_ip[ip_tenant_pub]['Subnets'][0] }}

最后,您的tenant_public_ip 示例字典不包含任何名为ip_<integer>_pub 的键,只有object_t<integer>_pub。为了使您的代码按预期工作,请将您的字典修改为:

tenant_public_ip: {'ip_1_pub': {'Subnets': ...}, ...}

或将您的模板修改为:

  - permit ip any {{ tenant_public_ip['object_t' + tenant | string + '_pub']['Subnets'][0] }}

就个人而言,我会选择前者(修改模板)。

【讨论】:

    猜你喜欢
    • 2019-06-14
    • 2014-05-20
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    • 2018-08-20
    • 2015-03-06
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多