创建自定义报表¶
SQL 视图是一种用于创建自定义报表的技术,用于展示现有模型字段和视图无法显示的数据。换句话说,这种技术有助于避免为数据分析目的而创建和计算额外的字段。
创建一个模型¶
一个 SQL 视图的创建方式与标准模型类似:
from odoo import fields, models
class ModuleReport(models.Model):
_name = 'module.report'
_description = "Module Report"
_rec_name = 'module_field'
_auto = False
其中的属性:
_auto = False
表示我们不希望将该模型存储到数据库中。_rec_name
指明了模型中哪个字段表示记录的名称(即在打开记录的表单视图时将在导航面包屑中使用的名称)。
并且其字段的定义方式与标准模型相同,只是每个字段都标记为 readonly=True
。
注解
不要忘记将你的新模型添加到安全文件中。
填充模型¶
有两种方法可以填充 SQL 视图的表:
重写
BaseModel.init()
方法,设置
_table_query
属性。
无论使用哪种方式,都会执行一个 SQL 查询来填充模型。因此,可以使用任何 SQL 命令来收集和/或计算所需的数据,您需要记住,您正在绕过 ORM(即,如果您还没有阅读过 安全在 Odoo 中,建议您先阅读一下)。从 SELECT
返回的列将填充模型的字段,因此请确保您的列名与字段名匹配,或者使用与字段名匹配的别名。
在大多数情况下,重写 BaseModel.init()
方法是标准且更好的选择。它需要导入 tools
,通常编写如下:
def init(self):
tools.drop_view_if_exists(self.env.cr, self._table)
self.env.cr.execute("""CREATE or REPLACE VIEW %s as (
SELECT
%s
FROM
%s
)""" % (self._table, self._select(), self._from()))
tools.drop_view_if_exists
确保在执行 SQL 查询时不会创建冲突的视图。通常会将查询的不同部分分开,以方便模型的扩展。查询如何跨方法拆分并没有统一的标准,但至少 _select
和 _from
方法是常见的,当然,所有这些方法都会返回字符串。
另请参见
示例:使用 BaseModel.init() 覆盖的 SQL 视图 <https://github.com/odoo/odoo/blob/18.0/addons/project/report/project_report.py>_
_table_query
属性用于当视图依赖于上下文时。它通常如下所示:
@property
def _table_query(self):
return 'SELECT %s FROM %s' % (self._select(), self._from())
并遵循与 BaseModel.init()
相同的 _select
和 _from
方法标准。
在多公司和多货币环境中,当用户在不同公司之间切换时,需要使用货币汇率将与货币相关的金额进行转换的情况下,应使用该属性而不是覆盖 BaseModel.init()
。
另请参见
示例:使用 _table_query 的 SQL 视图 <https://github.com/odoo/odoo/blob/18.0/addons/account/report/account_invoice_report.py>_
使用模型¶
您的 SQL 视图的视图和菜单项的创建和使用方式与任何其他 Odoo 模型相同。您已准备好开始使用您的 SQL 视图。祝您使用愉快!
额外提示¶
小技巧
一个在 SQL 视图中的常见错误是未考虑到由于表连接(JOIN)导致的某些数据重复。这可能会在使用字段的 aggregator
和/或透视表(pivot view)时导致计数错误。最好使用足够的数据来测试你的 SQL 视图,以确保生成的字段值符合你的预期。
小技巧
如果你有一个字段不希望作为度量值(即在你的透视表或图表视图中),请为其添加 store=False
,这样它将不会显示。