Как использовать Python Generator в Jinja2 Custom Filter - PullRequest
0 голосов
/ 07 апреля 2020

Мне нужно сгенерировать документ с буквенными индексами, как этот:

Channels:
 - A: Foobar item
 - B: Foobaz item
 - ...

У меня есть входной файл с Foobar, Foobaz, et c, и я хочу jinja2 для сгенерируйте его с помощью Indeces A, B, et c из файла шаблона, например:

Channels: {% for item in items %}
  - {{ None | next_id }}: {{ item.name }} item {% endfor %}

Я хочу использовать Генератор Python с этим шаблоном, но не могу найти рабочее решение, последняя версия кода:

...
# Simple letters generator
def idgen():
    value = 'A'
    while True:
        yield value
        value = (chr(ord(value)+1))

gen = idgen()

# Function to be used as Custom Filter
# https://jinja.palletsprojects.com/en/master/api/#writing-filters
# I don't know is it implementable without function, just with generator 
def next_id():
    return next(gen)

env = Environment(loader=FileSystemLoader(template_dir))
env.filters['next_id'] = next_id
template = env.get_template(template_filename)

# items = [{'name': 'Foobar'}, {'name': 'Foobaz'}]

print(next_id()) # To see if generator iterates
print(template.render(items=items))
print(next_id())

И соответствующий вывод:

B
Channels: 
  - A: Foobar item 
  - A: Foobaz item 

C

Нужна ваша помощь, улей.

1 Ответ

0 голосов
/ 07 апреля 2020

Я нашел только один обходной путь. Предположим, что Jinja использует какое-то кэширование / оптимизацию в зависимости от ввода функции пользовательского фильтра:

Здесь:

B
Channels: 
  - A: Foobar item 
  - A: Foobaz item 
C

Таким образом, наиболее очевидный способ - каждый раз отправлять новый ввод, ig {{ loop.index | next_id }}:

Шаблон:

Channels: {% for item in items %}
  - {{ loop.index | next_id }}: {{ item.name }} item {% endfor %}

Результат:

Channels: 
  - A: Foobar item 
  - B: Foobaz item  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...