【问题标题】:How to use Python Generator in Jinja2 Custom Filter如何在 Jinja2 自定义过滤器中使用 Python 生成器
【发布时间】:2020-07-19 00:10:35
【问题描述】:

我需要生成一个带有字母索引的文档,比如这个:

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

我有带有FoobarFoobaz 等的输入文件,我希望jinja2 从模板文件中使用索引AB 等生成它,如下所示:

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

我想用这个模板使用 Python Generator,但是我找不到可行的解决方案,最新的代码版本是:

...
# 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

需要你的帮助,蜂群。

【问题讨论】:

  • 我需要在模板{{ None | next_id }} 中发送None,因为 Jinja API 需要它。这是添加包装函数的两个原因之一。

标签: python jinja2 generator grafana dashboard


【解决方案1】:

到目前为止,我只找到了一种解决方法。假设 Jinja 根据自定义过滤器的功能输入使用某种缓存/优化:

这里:

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

所以最明显的解决方法是每次都发送新的输入,例如{{ loop.index | next_id }}:

模板:

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

结果:

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

【讨论】:

    猜你喜欢
    • 2021-10-24
    • 1970-01-01
    • 2011-12-23
    • 2012-01-10
    • 2021-09-21
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多