【问题标题】:jinja2.exceptions.TemplateSyntaxError: Encountered unknown tag 'do'jinja2.exceptions.TemplateSyntaxError:遇到未知标签'do'
【发布时间】:2021-04-10 19:33:07
【问题描述】:

我对 Jinja 不是很熟悉,并且在我的模板中使用“do”语句时遇到了一些问题。我正在阅读其他帖子,并试图修复它,但仍然没有运气。

这是我如何尝试调用它的部分输出。

注意:我的解释器说没有使用“扩展”:

import jinja2
import csv
from jinja2.ext import Extension


jinja_env = jinja2.Environment(extensions=['jinja2.ext.do'])

with open ('mycsv.csv') as f:
    read_csv = csv.DictReader(f)
    for line in read_csv:
        with open ( line["name"] +"_config.txt", 'w') as output:                    
            with open(r"My_Template.j2") as t:
                my_templ = t.read()

            temmplate = jinja2.Template(my_templ)
            output.write(temmplate.render(line))

这只是我想如何使用“do”的示例,而不是确切的模板(即单独的文件)

{%- for Z in range (1,X+1) %}
{%- do  Y-=1 %}
something {{Z}} something_else {{Y}}
{%- endfor %}

错误:

jinja2.exceptions.TemplateSyntaxError: Encountered unknown tag 'do'. Jinja was looking for the following tags: 'endfor' or 'else'. The innermost block that needs to be closed is 'for'.

===== 更新 ======

再次感谢!如果我在 Jinja 中定义我的变量,那效果很好。但是,如果我使用来自 csv 的变量,我会遇到一些问题。我希望输出如下:

increment 1 decrement 14
increment 2 decrement 13

所以这很好用。

{% set one = 1 %}
{% set fourteen = 14 %}
{% set base = 3 %}
{% for inc in range(base) %}
switch {{one+base}} priority {{fourteen - base}}
{% endfor %}

但如果我尝试使用 csv 中的变量,则所有内容都被视为字符串。如果我删除:

{% set base = 3 %}

我得到:

TypeError: "str" object cannot be interpreted as an integer.

所以我尝试修改神器:

{% set base = int(base) %}

{% set base = integer(base) %}

我分别得到以下两个错误:

jinja2.exceptions.UndefinedError: "int" is undefined
jinja2.exceptions.UndefinedError: "integer" is undefined

如果我在 python 中更改它,它会显示“未定义”:

base = int(line["base"])
print(base)
print(type(base))

Output:
3
<class 'int'>

  File "<template>", line 6, in top-level template code
TypeError: 'Undefined' object cannot be interpreted as an integer

这是第 6 行:

{% for inc in range(base) %}

有没有办法在 Jinja 模板中判断一个值是整数类型?

【问题讨论】:

  • 您没有使用jinja2.ext.Extension 模块是正确的。你不需要导入它。从您的问题中不清楚您是否遇到实际问题...do 命令是否在您的模板中工作?
  • 嗨,它不工作。我更新了 python 脚本的外观和我得到的错误。 j2 模板的部分位于最顶部。所有变量都取自 CSV,没有“do”部分它可以正常工作。模板中“do”的使用是错误的,还是我应该在 python 文件的其他地方引用它?或者扩展和环境可能有问题......

标签: python-3.x jinja2


【解决方案1】:

您的问题是,虽然您在 jinja_env 环境中启用了 do 扩展,但您并没有使用该环境来获取您的模板。如果您希望环境设置相关,则需要使用 jinja_env.get_template 方法加载模板。

例如,假设模板在当前目录中可用,我们可以这样重写您的代码:

import jinja2
import csv
from jinja2.ext import Extension


jinja_env = jinja2.Environment(
    loader=jinja2.FileSystemLoader('.'),
    extensions=['jinja2.ext.do']
)

with open ('mycsv.csv') as f:
    read_csv = csv.DictReader(f)
    for line in read_csv:
        with open("{name}_config.txt".format(**line), 'w') as output:
            template = jinja_env.get_template('My_Template.j2')
            output.write(template.render(line))

你会遇到第二个问题,那就是你使用 您示例中的 do 语句无效。你不会写……

{% do Y -= 1 %}

...因为那不是表达式。你可以解释“一个表达式” 作为“可以放在作业右侧的东西 声明”。所以这些是do 的有效用法示例:

{% do somevar.append('a value') %}
{% do somedict.setdefault('name', 'alice') %}

对于变量赋值,Jinja 有{% set ... %} 表达式。您可以使用它来减少变量。例如,这有效:

{% set x = 5 %}
{% set x = x - 1 %}

不幸的是,set 并没有像它那样修改一个变量 创建一个新的,这意味着这在 for 循环中不起作用 因为新变量的作用域是当前循环迭代。 也就是说,如果我们要写:

{% set x = 5 %}
{% for y in range(5) %}
{% set x = x - 1 %}
{{ x }}
{% endfor %}

输出将是:

4
4
4
4
4

但是,我们可以通过编写来获得我们正在寻找的行为:

{% set x = 5 %}
{% for y in range(5) %}
{{ x-y }}
{% endfor %}

这将产生:

5
4
3
2
1

【讨论】:

  • 非常感谢!我稍后会尝试这个,但我认为我可以在“do”语句中使用 +/-=1 递增/递减值
  • 好吧,我试过了,现在可以识别“do”语句,但我仍然很困惑如何在每次“for”迭代中减一。
  • 我添加了一些更新来解决您的问题。
  • 嘿,再次感谢!我还更新了我的第一篇文章,因为它有点长。简而言之,有没有办法在 Jinja 模板中判断一个值是整数类型?我尝试了几件事没有运气
猜你喜欢
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-12
  • 2019-09-12
  • 1970-01-01
相关资源
最近更新 更多