在Jinja2模板中比较对称字典

0 投票
2 回答
1238 浏览
提问于 2025-04-18 10:34

我正在把两个对称的字典传递给一个jinja2模板来渲染。这两个字典分别是“已安装”和“需要的”。我想比较这两个字典里的值,以确保它们的版本是一样的。版本号是以字符串的形式存储的。如果版本不相等,我想在我的表格中突出显示那一行。

虽然值打印出来是正确的,但比较的时候总是失败。

<table border="1">
  <tr>
    <td>Package</td>
    <td>Version Required</td>
    <td>Version Installed</td>
  </tr>

{% for key, value in required.items() %}
{% if installed[key] == required[key] %} 
    <tr>
    <td>{{key}}</td>
    <td>{{value}}</td>
    <td>{{installed[key]}}</td>
    </tr>
{% else %}
    <tr bgcolor="#ff0000">
    <td>{{key}}</td>
    <td>{{value}}</td>
    <td>{{installed[key]}}</td>
    </tr>
{% endif %} 
{% endfor %}
</table>

2 个回答

1

Jan的回答很棒,但我也发现了我遇到的具体问题。问题是其中一个字符串的末尾有一个特殊字符,而另一个没有。

我通过在每个字符串的末尾加上 .rstrip("\r\n") 来修复了代码。

你可以通过把每个字符串放进 len() 函数里,看看它们的长度来判断你是否遇到类似的问题。如果长度不一样,那就说明有特殊字符。

3

尽量把逻辑放在Python代码里,不要在jinja2模板中搞太复杂的逻辑,这样模板会更好用:

render.py

与其传两个字典,不如传一个包含元组的列表,格式是 (包名, 需要的版本, 已安装的版本)

from jinja2 import Template

with open("table.jinja2") as f:
    templ = Template(f.read())
required = {"boto": "1.1.1", "plac": "2.2.3", "pyyaml": "3.3.3", "jinja2": "4.4.4"}
installed = {"boto": "1.1.1", "plac": "2.2.2", "pyyaml": "3.3.3", "jinja2": "4.4.4"}

packages = [(key, installed[key], required[key]) for key in sorted(installed)]

print templ.render(packages=packages)

table.jinja2

在模板里,我们可以只修改 bgcolor,可以用硬编码的颜色代码,或者更好的是通过改变样式(这里没展示)。

我还在控制结构里使用了空格控制 -

<table border="1">
    <tr><td>Package</td> <td>Version Required</td><td>Version Installed</td></tr>
{%- for name, ver_required, ver_installed in packages %}
    <tr{% if ver_required != ver_installed %} bgcolor="#ff0000" {% endif %}>
        <td>{{name}}</td> <td>{{ver_required}}</td> <td>{{ver_installed}}</td>
    </tr>
{%- endfor %}
</table>

运行它:

$ python render.py >tabl.html

然后在网页浏览器中预览这个表格。

<table border="1">
    <tr><td>Package</td> <td>Version Required</td><td>Version Installed</td></tr>
    <tr>
        <td>boto</td> <td>1.1.1</td> <td>1.1.1</td>
    </tr>
    <tr>
        <td>jinja2</td> <td>4.4.4</td> <td>4.4.4</td>
    </tr>
    <tr bgcolor="#ff0000" >
        <td>plac</td> <td>2.2.2</td> <td>2.2.3</td>
    </tr>
    <tr>
        <td>pyyaml</td> <td>3.3.3</td> <td>3.3.3</td>
    </tr>
</table>

撰写回答