python-3.x - jinja2.exceptions.TemplateSyntaxError:遇到未知标签'do'
问题描述
我对 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 模板中判断一个值是整数类型?
解决方案
您的问题是,当您在环境中启用do
扩展时jinja_env
,您并没有使用环境来获取模板。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
推荐阅读
- kubernetes - 如何将 gRPC unix socket 传递给 Kubernetes api-server
- mysql - MySQL存储过程不插入数据
- php - 如何使用 php 连接亚马逊 RDS 数据库
- asp.net-mvc - MVC 视图模型返回 NULL
- angular - 局部布尔变量在 PrimeNG 的 p 表内不服从
- rust - 使用方法借用包装在选项中的值
- ruby - 循环遍历数组并将具有新键的数据添加到单独数组中的散列中
- git - 在 GitLab 的 CI/CD 系统中,如果作业在我的 fork 中,我如何防止它运行,并且只有在它合并到主仓库时才允许它运行?
- json.net - [A]Newtonsoft.Json.Linq.JObject 无法转换为 [B]Newtonsoft.Json.Linq.JObject。A 型源自 'Newtonsoft.Json, Version=9.0.0.0
- mobile - Appium:点击复选框时显示元素不可交互错误