今天在工作中遇到一个这样的问题。要求:做一个打印模板实现下面图中的分类汇总
py3o://for="o in object.delivery_containers_line.read_group(domain=[('delivery_order_id','=',object.id)], fields=['customer_id', 'delivery_order_id', 'sales_order_id', 'supplier_id','purchase_currency','customer_material','outstock_qty:sum','outstock_purchase_amount:sum','outstock_purchase_utaamount:sum','outstock_sale_amount:sum'],groupby=['customer_id', 'delivery_order_id', 'sales_order_id', 'supplier_id','purchase_currency','customer_material'], lazy=False)"
我用的是odoo12中py3o的模板
下面来分析上面代码的作用
1. read_group
方法:
read_group
是 Odoo 的一个用于对模型数据进行分组和聚合的方法。它通常用于生成报表时需要对数据进行按字段分组的场景。
语法:
read_group(domain, fields, groupby, lazy=False)
参数解释:
domain
: 查询的过滤条件。domain=[('delivery_order_id','=',object.id)]
指定了只有与当前delivery_order_id
匹配的记录才会被选中。fields
: 需要返回的字段和汇总的字段。例如:'customer_id'
,'delivery_order_id'
,'sales_order_id'
, 等这些字段将按组进行分组。outstock_qty:sum
,outstock_purchase_amount:sum
等这些字段将在每组中进行汇总,汇总方法是sum
。
groupby
: 指定用于分组的字段。这里的数据会按照customer_id
,delivery_order_id
,sales_order_id
, 等字段进行分组,意味着数据会被按这些字段的不同组合拆分。lazy=False
: 指定是否使用懒加载,False
代表一次性加载所有数据。
2. 字段汇总(聚合):
在 fields
中,字段后面加上 :sum
是 Odoo 提供的一种简便方式来进行汇总操作。例如:
outstock_qty:sum
:表示对所有outstock_qty
字段进行求和。outstock_purchase_amount:sum
:表示对所有outstock_purchase_amount
字段进行求和。
3. for="o in object.delivery_containers_line.read_group(...)"
:
这个 for
循环是用来遍历 read_group
返回的聚合数据结果。每一项 o
代表一个分组的结果对象。在这个对象中:
o['customer_id']
:是分组依据的字段之一。o['outstock_qty:sum']
:是该组所有outstock_qty
字段的汇总值。
4. 模板中的数据展示:
模板中的数据展示逻辑会依赖于 read_group
返回的结果。比如,我们可以将汇总的字段显示在模板中。
<span t-esc="o['outstock_qty:sum']"/> <!-- 显示分组后的 outstock_qty 的总和 -->
知识点归纳和总结
1. read_group
关键用法:
read_group
是 Odoo 提供的强大聚合工具,适用于报表生成和数据分析。domain
用于过滤数据,groupby
用于按指定字段分组,fields
用于选择和聚合字段。- 汇总函数:常用的聚合函数包括
sum
、avg
、min
、max
等。
2. 模板中的 for
循环:
- 在报告模板中,
for
循环是遍历分组数据并动态显示数据的核心。 t-esc
用于将数据嵌入 HTML 中并显示。
3. Py3O 和 LibreOffice 打印:
- Py3O 是 Odoo 中用于将报告导出为各种格式(如 PDF、Excel)的工具之一,通常通过模板生成报表。
- LibreOffice 作为兼容的办公软件,支持 Odoo 的打印功能,适用于不同的报表格式。
经验总结:如何处理类似问题
基于以上分析,下面总结一个公式或流程,可以帮助你快速处理类似的问题:
常用的处理步骤公式:
-
选择分组字段:
- 确定需要分组的数据字段,例如
customer_id
,delivery_order_id
等。 - 选择分组的依据字段时,应考虑业务需求,如订单号、客户、供应商等。
- 确定需要分组的数据字段,例如
-
选择需要聚合的字段:
- 确定需要进行聚合(如求和、平均等)的字段。
- 格式:
字段名:sum
,字段名:avg
等。
-
构建
read_group
查询:- 使用
domain
筛选数据。 - 使用
groupby
按字段分组。 - 在
fields
中选择聚合字段及分组字段。
- 使用
-
模板中显示数据:
- 在报告模板中,使用
for
循环遍历read_group
返回的数据。 - 使用
t-esc
显示字段数据。
- 在报告模板中,使用
-
处理空值和边界情况:
- 在模板中要处理好空值和不符合预期的数据长度问题。例如,检查数据的存在性和长度,避免错误。
-
定期验证结果:
- 确保聚合字段的计算和显示是正确的。对于大数据量的报表,可以做性能优化,使用缓存等策略。
总结公式:
对于业务逻辑中“分组并汇总”的问题,可以使用以下模板公式:
object.MODEL_NAME.read_group( domain=[('field', '=', value)], fields=['field_to_group', 'field_to_aggregate:sum', 'field_to_aggregate:avg'], groupby=['field_to_group'], lazy=False )
在模板中,您可以遍历这个结果并显示汇总数据:
<t t:for="o in object.MODEL_NAME.read_group(...)"> <span t-esc="o['field_to_aggregate:sum']"/> </t>
最佳实践总结:
- 合适的
domain
过滤条件:始终根据报表需求制定合适的过滤条件,确保提取的数据是正确和有意义的。 - 性能优化:对于大规模数据,
read_group
是非常高效的,但也要注意避免不必要的查询,可以考虑使用索引和分页。 - 异常处理:确保在模板中对可能的空值或边界情况进行处理,以避免报错。