Jinja 2 - 忽略破折号但仍在处理领域?

时间:2018-05-03 11:40:06

标签: python jinja2

下午好,

我有下面的Jinja字段:

{{ DEVICE_RTR-02:LOOPBACK_SUBNET }}

当此文件名通过渲染

运行时
expected token 'end of print statement', got ':'

所以我交换了:for a ++而不是

'DEVICE_RTR' is undefined

对我来说,看起来它可能会将破折号作为一个函数?

我尝试按照以下方式转义它,只是忽略整个字段

{{ 'DEVICE_RTR-02++LOOPBACK_SUBNET' }}

我需要使用一个在我的函数中拆分的分隔符char来获取正确的数据。以及 - 是如何命名数据的。

有没有办法逃脱所有字符但处理其中的数据?或者有谁知道我可以交换什么价值来使这项工作?

背景函数如下,这应该让我知道我在做什么:

field_names = re.findall(r'(?s)(?<={{)(.*?)(?=}})', template.config, flags=re.S)
for i, field in enumerate(field_names):
    data = field
    data = data.strip()
    data = data.lower()
    if '|' in data:
        data = data.split('|')[0]
    field_names[i] = data

field_names = list(set(field_names))
template_data = {}
for name in field_names:
    # reset the device_data incase it was altered with the alt name
    device_data = Device.objects.get(id=device_id)
    if '++' in name:
        alt_data = name.split('++')[0]
        if alt_data.startswith('device_'):
            alt_data = alt_data.split('_')
            device_data = Device.objects.get(site_id=device_data.site_id,hostname__icontains=alt_data[1])    
            alt_field_data = get_field_data(name.split('++')[1])

            alt_field_data[name.upper()] = alt_field_data.pop(name.split('++')[1].upper())
            template_data = {**template_data, **alt_field_data}
        else:
            template_data = {**template_data, **get_field_data(name.split('++')[1])}
    else:
        template_data = {**template_data, **get_field_data(name)} 

由于

1 个答案:

答案 0 :(得分:1)

字段已处理,因为您用来匹配它们的正则表达式是(.*?),它匹配任何。但是,Jinja2 docs表示使用此正则表达式匹配标识符:

[a-zA-Z_][a-zA-Z0-9_]*

所以我猜你唯一的选择是使用下划线作为&#34;控制字符&#34;。一种可能的解决方案如下:

生成模板时

在生成Jinja2 模板字段时,请使用:

  • 加倍下划线(__)代替短划线(-);
  • 三倍下划线(___)作为分隔符,而不是++;
  • 一个下划线作为设备名称分隔符(就像您已经做过的那样)。

解析模板

您可以在上面的Python代码中替换for循环,例如:

for name in field_names:
    # reset the device_data incase it was altered with the alt name
    device_data = Device.objects.get(id=device_id)
    if '___' in name: # look for separator
        alt_data = name.split('___')[0]
        if alt_data.startswith('device_'):
            hname = alt_data[7:] # this line has changed
            device_data = Device.objects.get(site_id=device_data.site_id,hostname__icontains=hname)    
            alt_field_data = get_field_data(name.split('___')[1])

            alt_field_data[name.upper()] = alt_field_data.pop(name.split('___')[1].upper())
            template_data = {**template_data, **alt_field_data}
        else:
            template_data = {**template_data, **get_field_data(name.split('___')[1])}
    else:
        template_data = {**template_data, **get_field_data(name)}