来自此json:
{
"obj": [
{
"int": 0
},
{
"int": 1
}
]
}
我想获取字段int
的{{1}}属性的列表,以便可以对该列表进行汇总,例如使用Jinja2语法取obj
中int
的平均值。
我尝试将过滤器obj
与selectattr("int")
过滤器结合使用,但得到+的'不受支持的操作数类型:'int'和'dict'。
我正在使用Jinja2和sum
从模板生成docx文件。
docxtpl
docx模板包含一行:
import json
j = '{"obj": [{"int": 0},{"int": 1}]}'
context = json.loads(j)
from docxtpl import DocxTemplate
import jinja2
tpl = DocXtemplate('template.docx')
tpl.render(context, jinja_env)
tpl.save('out.docx')
我想像上面一样尝试在求和时在doxc文件中看到{{obj|selectattr("int")|sum}}
,我也希望能够得出均值并最终在其他操作中重用它。
编辑:作为对那些我应该在python中执行此操作的回答:
我正在开发一种用于从数据库和模板文件生成docx报告的工具。该工具的第一部分是一个C ++程序,该程序从数据库生成json数据。第二部分是使用Jinja2从模板生成docx格式的报告的脚本。我希望用户仅弄乱模板,而不必修改脚本,我也希望具有某种模块化,并能够计算json树上的聚合。由于Jinja2在列表和其他类型的操作上提供了1
,因此我认为它可以增加另一层模块化,而无需编写更多代码。目前,我已经为用户增加了在json树上进行聚合并将其插入节点树的可能性,但是我的解决方案并不完美,其代价是提供了另一个模板文件以进行数据生成,这使得工具更复杂。
我希望现在更有意义,为什么我不想在脚本中这样做。
Edit2 :一个稍微复杂的示例:
sum
我希望能够做类似的事情:
{
"arr": [
{
"obj": [
{
"name": 0
},
{
"name": 1
}
]
},
{
"obj": [
{
"name": 0
},
{
"name": 1
}
]
}
]
}
更好的解决方案将是可以直接在Jinja2中进行列表扩展:
{{arr|get_attr_list('obj')|get_attr_list('int')}}
答案 0 :(得分:3)
这绝对不是您在Jinja中应该做的事情。这是用于显示内容的模板语言。
您应该在Python中做到这一点,这是一个简单的单行代码:
sum(item["int"] for item in context["obj"])
答案 1 :(得分:0)
这里
d= {
"obj": [
{
"int": 0
},
{
"int": 1
}
]
}
# create a list
lst = [e['int'] for e in d['obj']]
print(lst)
# now you can do stats on this list
import statistics
mean = statistics.mean(lst)
print(mean)
答案 2 :(得分:0)
完整的答案适用于简单和稍微复杂的示例:
我可以提供一个返回列表的过滤器,为了构成它,我应该检查感兴趣的字段是否是列表,如果是这样,我应该将结果展平。需要进一步定义边框大小写,但它可以起作用:
def get_list(value, arg):
if type(value) is dict:
return value[arg]
elif type(value) is list:
if len(value) == 0:
return []
else:
res = [ x[arg] for x in value ]
if type(res[0]) is list:
res = list(itertools.chain(*res))
return res
else:
return value
然后按预期工作:
第一个示例
{{ obj|get_list("int")|sum }}
(输出1)
第二个示例
{{ arr|get_list("obj")|get_list("int")|sum }}
(输出2)