Python Jinja2模板用字符串渲染

时间:2018-02-19 11:54:12

标签: python templates jinja2 render

我正在尝试使用Jinja2渲染html模板 - 放入从Pandas数据帧中提取的变量值。目前我将变量硬编码到render命令中,如下所示:

template_loader = jinja2.FileSystemLoader(searchpath=template_dir)
template_env = jinja2.Environment(loader=template_loader)
template_file = "report.html"
template = template_env.get_template(template_file)
html_code = template.render(reg=reg.iat[0, 0], ac=ac.iat[0, 0],
                            su_new=su_new.iat[0, 0], chu_new=chu_new.iat[0, 0],
                            title_0=play.iat[0, 0], title_0_count=play.iat[0, 1],
                            title_1=play.iat[1, 0], title_1_count=play.iat[1, 1],
                            title_2=play.iat[2, 0], title_2_count=play.iat[2, 1])

问题是,有时候,“play”数据帧中没有第三行,这会返回索引错误(因为那里没有元素)。

我已经创建了一个准备变量的循环,可以将其插入到render命令中,如下所示:

template_variables = "reg=reg.iat[0, 0], ac=ac.iat[0, 0],su_new=su_new.iat[0, 0], chu_new=chu_new.iat[0, 0], "

for i in range(play.shape[0]):
    template_variables += str("title_" + str(i) + "=play.iat[" + str(i) + ", 0], title_" + str(i) + "_count=play.iat[" + str(i) + ", 1], ")

template_variables = template_variables.rstrip(", ")

template_loader = jinja2.FileSystemLoader(searchpath=template_dir)
template_env = jinja2.Environment(loader=template_loader)
template_file = "report.html"
template = template_env.get_template(template_file)
html_code = template.render(template_variables)

有了这个,我收到了以下错误:

  

ValueError:字典更新序列元素#0的长度为1; 2是必需的

我认为背后的原因是我创建了一个字符串,不能在Jinja2 render命令中使用。知道是否有可能将字符串传递给该命令,或者我是否必须找到另一种方法来解决基于Dataframe大小提取元素的问题?

谢谢你,最诚挚的问候, 波斯蒂安

2 个答案:

答案 0 :(得分:1)

我做了一些挖掘并想出了解决方案。我在这里发布它,以防其他人有类似的问题。 正如所料,问题在于它是一个字符串。所以最初我准备了相同的字符串(更改","" |"作为&#34的分隔符;"也包含在iat命令中)。然后我用字符串创建了字典并在template.render()中使用它。 以下是代码:

template_variables = "reg=" + str(reg.iat[0, 0]) + "|ac=" + str(ac.iat[0, 0]) + "|su_new=" + str(su_new.iat[0, 0]) + "|chu_new=" + str(chu_new.iat[0, 0]) + "|"

for i in range(play.shape[0]):
    template_variables += "title_" + str(i) + "=" + str(play.iat[i, 0]) + "|title_" + str(i) + "_count=" + str(play.iat[i, 1]) + "|"

template_variables = template_variables.rstrip("|")
template_variables = dict(map(lambda variable: variable.split('='), template_variables.split('|')))

template_loader = jinja2.FileSystemLoader(searchpath=template_dir)
template_env = jinja2.Environment(loader=template_loader)
template_file = "report.html"
template = template_env.get_template(template_file)
html_code = template.render(template_variables)

这可能不是最优雅的方式,但它似乎可以解决问题。

祝你好运, 波斯蒂安

答案 1 :(得分:0)

您无需花很多精力从字符串构造字典,而是可以使用文字轻松创建一个字典:

template_variables = dict(
    reg=reg.iat[0, 0],
    ac=ac.iat[0, 0],
    su_new=su_new.iat[0, 0],
    chu_new=chu_new.iat[0, 0],
    titles=[
        {"name": play_iat[i,0], "count": play_iat[i,1]}
        for i in range(len(play_iat))
    ]
)

html_code = template.render(template_variables)

然后,在模板中,您将引用regacsu_newchu_new 变量(例如{{ reg }}),然后使用类似下面的内容列出 titles变量:

{% for title in titles %}
    Name: {{ title.name }}, Count: {{ title.count }}
{% endfor %}

titles构造函数中dict条目中的特殊魔术是列表理解, 它将根据从您指定的序列中获取的项目来构建事物列表(在这种情况下,整数索引为play_iat。)因此,每次理解时 range序列中的整数,它根据片段构造另一个字典 指定的play_iat中的第一个,并将该字典添加到它正在构建的列表中。然后 将列表放到dict键下的外部titles中。

模板在for循环中引用titles的列表,抓取每个列表并放置 将其放入item变量中,您可以在其中使用点语法引用相应内部词典的namecount字段。