Джинджа 2 - игнорируя тире, но все еще обрабатывая поле? - PullRequest
0 голосов
/ 03 мая 2018

Добрый день,

У меня есть поле ниже Jinja:

{{ DEVICE_RTR-02:LOOPBACK_SUBNET }}

Когда это имя файла проходит через рендер

expected token 'end of print statement', got ':'

поэтому я поменял местами: для ++, а затем я получил

'DEVICE_RTR' is undefined

Что для меня похоже на то, что он принимает символ тире как функцию, возможно?

Я пытался избежать его согласно приведенному ниже, который просто игнорирует все поле

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

Мне нужно использовать символ-разделитель, который я разделил в своей функции, чтобы получить правильные данные. и - как данные названы.

есть ли способ избежать всех символов, кроме обработки данных в нем? или кто-нибудь знает, какие значения я могу поменять, чтобы заставить это работать?

Фоновая функция ниже, которая должна дать представление о том, что я делаю:

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 голосов
/ 07 мая 2018

Поля обрабатываются, потому что регулярное выражение, которое вы используете для сопоставления, равно (.*?), что соответствует что угодно . Но в Jinja2 документах говорится, что идентификаторы сопоставляются с помощью этого регулярного выражения:

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

Так что, я думаю, ваш единственный вариант - использовать подчеркивание в качестве «управляющего символа». Одним из возможных решений может быть следующее.

Когда шаблон генерируется

В момент генерации полей шаблона Jinja2 используйте:

  • двойное подчеркивание (__) вместо тире (-);
  • тройное подчеркивание (___) в качестве разделителя вместо ++;
  • один в качестве разделителя имени устройства (как вы уже сделали).

Разбор шаблона

Вы можете заменить цикл for в приведенном выше коде Python, например, например ::1010*

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)} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...