1)概念
- 计算字段是只读的,因为它从记录集即时计算值
- odoo的计算字段默认不保存在数据库中,使用的时候在进行计算
- 不能用作domain的筛选或其他函数中引用该字段使用
- 可以使用store=True强制保存到数据库中,但是加了store=True表示该字段只能计算一次,可以通过@api.depends(‘employee_id’) ,通过employee_id的变动来触发执行计算函数
- 要想修改计算字段,就要在字段定义中加入inverse属性inverse=‘函数名’,通过给出反函数来完成。Invserse 通俗点讲的话,他是 Compute 的相反设置。我们在 field 中设置了它对应的 Compute 计算方法,那么这个字段就变成了只读的,这时候我们可以设置 inverse,来达到为该字段赋值的目的。设置了 inverse 这个,字段就可以在前端直接编辑,赋值就是通过这个 inverse 设置的方法
2)使用
upper=fields.Char(compute='_compute_upper',inverse='_inverse_upper', search='_search_upper')
@api.depends('employee_id')
def _compute_upper(self):
for rec in self:
rec.upper = rec.employee_name.upper() if rec.employee_name else False
def _inverse_upper(self):
for rec in self:
rec.employee_name = rec.upper.lower() if rec.upper else False
3) 案例
部门人数计算需要判断父子关系,可以简化为只判断是否有儿子的情况
- 无子部门,直接计算部门成员的数量
- 有子部门,先计算当前部门人数,再遍历进入子部门去计算子部门成员人数,累加计算得出部门成员数量
# store定义了该动态改变的字段值是否保存到数据库表中
employee_count = fields.Integer(compute="_compute_employee_count", string="部门人数",api=True)
# 计算部门人数
def _compute_employee_count(self): # self: department:ogsp.departmen t(3,4,5,6,9)
for record in self:
self.get_employee_count(record, record)
def get_employee_count(self, record, j):
if len(j.sons) != 0:
record.employee_count += len(j.employees)
for j2 in j.sons:
self.get_employee_count(record, j2)
else:
record.employee_count += len(j.employees)
4) 扩展
写法:
def _compute_xx(self):
model_objs = self.env['model的_name']
result = model_objs.search([domain表达式])
或
def _compute_xx(self):
self.env.cr.execute(SQL语句)
result = self.env.cr.fetchall()
例子:
i_p = fields.Char(compute='_get_i_p', api=True)
默认写法:
def _get_i_p(self):
i_p_obj = self.env['yp32011.inspection_procedure']
result = i_p_obj.search([('id', '=', 1),])
SQL语句写法:
def _get_i_p(self):
self.env.cr.execute("select * from yp32011_inspection_procedure")
result = self.env.cr.fetchone()