ODOOv10字段值联动及hr.employee同步至自定义模型代码咨询
嘿,我来帮你搞定这两个Odoo v10的实际开发问题,都是日常开发里经常碰到的场景,咱们一步步拆解:
问题1:如何在Odoo v10中根据其他字段的值修改目标字段的值?
根据你的需求场景,有三种常用方案,你可以按需选择:
方案1:用@api.onchange实现前端实时更新
如果需要用户在表单里编辑依赖字段时,立刻看到目标字段的变化,这个方法最适合。比如计算总价的场景:
from odoo import models, fields, api class YourCustomModel(models.Model): _name = 'your.custom.model' unit_price = fields.Float(string='单价') quantity = fields.Integer(string='数量') total_amount = fields.Float(string='总价') @api.onchange('unit_price', 'quantity') def _onchange_calculate_total(self): for record in self: # 当单价和数量都有值时计算总价,否则置0 record.total_amount = record.unit_price * record.quantity if (record.unit_price and record.quantity) else 0.0
@api.onchange会监听括号里的字段,只要这些字段值变了,就自动触发方法更新目标字段,完全是前端实时反馈,不用点保存。
方案2:用计算字段(compute属性)自动同步
如果目标字段的值完全由其他字段决定,不需要手动修改,那计算字段是最优解——Odoo会自动处理依赖关系,不用你手动触发更新:
from odoo import models, fields, api class YourCustomModel(models.Model): _name = 'your.custom.model' unit_price = fields.Float(string='单价') quantity = fields.Integer(string='数量') total_amount = fields.Float( string='总价', compute='_compute_total_amount', store=True # 加上这个会把计算结果存到数据库,方便后续查询 ) @api.depends('unit_price', 'quantity') def _compute_total_amount(self): for record in self: record.total_amount = record.unit_price * record.quantity if (record.unit_price and record.quantity) else 0.0
这里@api.depends声明了计算依赖的字段,只要这些字段改动,Odoo会自动重新计算目标字段的值。如果不需要存到数据库,去掉store=True就行,每次访问都会动态计算。
方案3:重写write/create方法在保存时更新
如果你的逻辑比较复杂(比如需要关联其他模型操作),或者只需要在记录保存时才更新目标字段,那就重写这两个核心方法:
from odoo import models, fields, api class YourCustomModel(models.Model): _name = 'your.custom.model' source_field = fields.Char(string='源字段') target_field = fields.Char(string='目标字段') @api.multi def write(self, vals): # 先判断是否修改了源字段,如果是,提前处理目标字段的值 if 'source_field' in vals: vals['target_field'] = vals['source_field'].upper() # 比如把源字段转大写赋值给目标字段 # 调用父类方法完成保存 res = super(YourCustomModel, self).write(vals) # 也可以在保存后做额外操作,比如更新关联记录 return res @api.model def create(self, vals): if 'source_field' in vals: vals['target_field'] = vals['source_field'].upper() # 创建记录并返回 return super(YourCustomModel, self).create(vals)
这个方法不管是前端编辑还是后台批量修改,都能保证目标字段被正确更新,适用性很广。
问题2:hr.employee字段同步到自定义模型的代码实现
假设你的自定义模型叫custom.employee,先定义好模型结构(记得加关联字段确保一对一对应):
from odoo import models, fields, api class CustomEmployee(models.Model): _name = 'custom.employee' name = fields.Char(string='员工姓名') birthday = fields.Date(string='生日') employee_id = fields.Many2one('hr.employee', string='关联员工', unique=True)
接下来继承hr.employee模型,重写write和create方法,实现字段同步:
from odoo import models, fields, api class HrEmployee(models.Model): _inherit = 'hr.employee' @api.multi def write(self, vals): # 先保存hr.employee的修改 res = super(HrEmployee, self).write(vals) # 检查是否修改了name或birthday字段 if 'name' in vals or 'birthday' in vals: for emp in self: # 查找对应的自定义模型记录 custom_emp = self.env['custom.employee'].search([('employee_id', '=', emp.id)], limit=1) update_data = {} if 'name' in vals: update_data['name'] = vals['name'] if 'birthday' in vals: update_data['birthday'] = vals['birthday'] if custom_emp: # 更新现有记录 custom_emp.write(update_data) else: # 如果没有对应记录,自动创建(根据你的业务需求可选) self.env['custom.employee'].create({ 'name': emp.name, 'birthday': emp.birthday, 'employee_id': emp.id }) return res @api.model def create(self, vals): # 创建hr.employee记录 new_emp = super(HrEmployee, self).create(vals) # 在自定义模型创建对应记录 self.env['custom.employee'].create({ 'name': new_emp.name, 'birthday': new_emp.birthday, 'employee_id': new_emp.id }) return new_emp
额外补充:
- 如果需要删除员工时同步删除自定义模型的记录,可以再加一个
unlink方法:
@api.multi def unlink(self): # 删除关联的自定义员工记录 custom_emps = self.env['custom.employee'].search([('employee_id', 'in', self.ids)]) custom_emps.unlink() return super(HrEmployee, self).unlink()
- 如果你的自定义模型已经有旧数据,记得先写个小脚本把现有员工和自定义记录关联起来,避免重复创建。
内容的提问来源于stack exchange,提问作者Prashanth K
相关产品推荐
相关产品推荐

