Odoo 16创建子项时自动保存父项的实现方案
在Odoo 16中创建未保存父对象的子对象解决方案
核心思路是:当创建子对象时,先检测关联的父对象是否为未保存的临时记录,若是则先保存父对象生成真实ID,再将子对象与真实父ID关联后创建。重写子模型的create()方法是最直接的实现方式,具体步骤如下:
1. 重写子模型的create()方法
假设父模型为parent.model,子模型为child.model,子模型包含关联父对象的字段parent_id。在子模型中继承并重写create()方法:
from odoo import models, api class ChildModel(models.Model): _inherit = 'child.model' @api.model def create(self, vals): parent_id = vals.get('parent_id') if parent_id: parent_record = self.env['parent.model'].browse(parent_id) # 判断父对象是否为未保存的临时记录(临时ID为负数,exists()返回False) if not parent_record.exists(): # 提取临时父记录的所有已填写字段值 parent_vals = {} for field_name in parent_record._fields: field_value = parent_record[field_name] # 排除空值和Odoo内部字段 if field_value and field_name not in ['id', 'create_date', 'write_date']: parent_vals[field_name] = field_value # 创建真实父对象 new_parent = self.env['parent.model'].create(parent_vals) # 替换子对象的父ID为真实ID vals['parent_id'] = new_parent.id # 调用原生create方法创建子对象 return super(ChildModel, self).create(vals)
代码说明
- Odoo中未保存的临时记录会生成负数临时ID,通过
exists()方法可判断该记录是否已持久化到数据库。 - 提取临时父记录的字段值时,需排除空值和Odoo内部维护的字段(如
id、create_date),避免创建父对象时出错。 - 创建真实父对象后,将子对象的
parent_id替换为真实ID,再执行原生创建逻辑。
2. 额外优化建议
- 必填字段校验:在代码中添加父对象必填字段的检查,确保创建父对象时不会因缺少必填项抛出异常。
- 前端表单适配:如果是在父对象表单内的子列表创建子对象,可在父表单的字段中设置
force_save="1",确保父对象的临时变更能被正确提取。
内容的提问来源于stack exchange,提问作者Konark
相关产品推荐
相关产品推荐

