You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 05:22:33