Onchange with Compute Method
Onchange 和Compute Method是 odoo 中主要用于实现某种业务逻辑的技术。计算字段是使用其他字段的值计算其值的字段。用于计算计算字段值的方法通常称为计算方法,而由字段值更改触发的方法是 onchange 方法。
让我们在一个例子的帮助下讨论这两种情况。考虑一个管理租赁订单的业务模型,其中总租金金额是根据单位持续时间的持续时间和价格计算的。为此,让我们在下面的代码中定义一个货币字段 total_rent,它是一个计算字段,其中该字段的值是使用另一个字段或多个字段的值计算的。
from odoo import models, fields
class VehicleRental(models.Model):
_name = "vehicle.rental"
_description = "Vehicle Rental"
hour_rate = fields.Monetary(string="Hour Rate",)
hours = fields.Integer(string="Hours")
total_rent = fields.Monetary(string='Total Rent',
compute='_compute_total_rent')
def _compute_total_rent(self):
for record in self:
record.total_rent = record.hour_rate*record.hours
通常,计算域的值依赖于其他域。因此,最好在计算方法中包含依赖关系。ORM 期望开发人员在方法上使用装饰器depends()指定这些依赖项。每当依赖字段发生任何变化时,ORM 都会使用给定的依赖关系来触发计算方法。
from odoo import models, fields, api
class VehicleRental(models.Model):
_name = "vehicle.rental"
_description = "Vehicle Rental"
hour_rate = fields.Monetary(string="Hour Rate",)
hours = fields.Integer(string="Hours")
total_rent = fields.Monetary(string='Total Rent',
compute='_compute_total_rent')
@api.depends('hour_rate', 'hours')
def _compute_total_rent(self):
for record in self:
record.total_rent = record.hour_rate*record.hours
如果对其他字段进行了任何更新,Odoo 中的 onchange 机制使该功能能够修改或更新字段的值。此外,当在表单视图中修改给定字段之一时将触发onchange,即它们仅在表单视图中触发。在给定的示例中,租赁订单的参考是通过一种方法实现的。onchange() 装饰器使该功能能够 在vehicle_id时触发onchange方法表单中的字段更改其值。
from odoo import models, fields, api
class VehicleRental(models.Model):
_name = "vehicle.rental"
_description = "Vehicle Rental"
name = fields.Char(string="Ref.")
vehicle_id = fields.Many2one('fleet.vehicle', string="Vehicle")
@api.onchange('vehicle_id')
def _onchange_vehicle(self):
self.name = "Rental Order for %s" % self.vehicle_id.name
基于 SQL 视图的模型(postgresql 的 view)
在大多数情况下,我们会创建一个定义了字段的模型类。这将通过 Odoo 映射到数据库表。可能在某些情况下,我们需要将来自多个模型的数据聚合到单个表中。这可能对制作仪表板或生成报告。利用 odoo 中的 postgresql 数据库引擎,可以通过 postgresql 视图而不是数据库表创建只读模型后端。
让我们借助一个例子来讨论它。考虑一个模型 student.student,它存储了一个教育组织的所有学生详细信息。
- 1. 创建一个新模型,_auto 属性设置为 False。
class StudentLeaveStatistics(models.Model):
_name = 'student.leave.statistics'
_auto = False
- 2. 为模型定义字段并将 readonly 属性设置为 False,以便视图不会启用您无法保存的修改,因为 PostgreSQL 视图是只读的。
student_id = fields.Many2one('student.student', string="Student", readonly=True)
leave_count = fields.Integer(string="Leave Count", readonly=True)
- 3. 下一步是定义init()方法来创建视图。该方法负责在auto 属性设置为False 时创建表。否则,这无济于事。视图创建查询必须创建一个列名与模型的字段名匹配的视图。
def init(self):
tools.drop_view_if_exists(self._cr, 'student_leave_statistics')
self._cr.execute(""" create or replace view student_leave_statistics as (
select min(sl.id) as id,
sl.student_id as student_id,
count(sl.id) as leave_count,
from student_leave as sl join student_student as s ON s.id = sl.student_id
where sl.state = 'done' )""")
- 4. 您现在可以为新模型定义视图。透视视图对于探索数据特别有用