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

Odoo如何在非继承场景下实现跨模型字段依赖

为什么你之前用@api.depends的方案不生效

首先要纠正对@api.depends跨模型能力的误解:这个装饰器的跨字段追踪,仅支持当前模型持有关联外键时,向上监听被关联模型的字段变化。

举个例子,你的自定义模型如果有个partner_id = fields.Many2one('res.partner')字段,写计算字段时依赖partner_id.x_float_1、partner_id.x_float_2是合法的,但这个触发逻辑有严格的前提:
只有当你在操作自定义模型记录、连带触发关联字段链路重算时,才会执行重算。如果用户单独打开res.partner的表单修改那两个Float字段,自定义模型的记录根本不会被触发重算——这就是你写了依赖但没效果的核心原因,装饰器从设计上就不负责监听独立模型的反向字段变更。

可落地的实现方案

方案1:在res.partner侧重写write方法,主动反向同步字段

这是最稳定、性能可控的代码实现方式,核心逻辑是在res.partner的字段更新入口,检测需要同步的字段是否发生变化,反向找到所有关联该partner的自定义模型记录,批量更新对应值。

示例代码:

class ResPartnerExtension(models.Model):
    _inherit = 'res.partner'

    # 你新增的两个Float字段
    x_sync_float_a = fields.Float(string='同步浮点值A')
    x_sync_float_b = fields.Float(string='同步浮点值B')

    def write(self, vals):
        # 先执行原生写入逻辑,保证原有流程不受影响
        write_result = super().write(vals)
        # 定义需要同步的字段清单
        SYNC_TARGET_FIELDS = ['x_sync_float_a', 'x_sync_float_b']
        # 判断本次写入是否涉及需要同步的字段
        need_sync = any(field in vals for field in SYNC_TARGET_FIELDS)
        if need_sync and self:
            # 收集所有需要同步的partner ID,避免循环查询造成N+1性能问题
            partner_id_list = self.ids
            # 一次性查出所有关联这些partner的自定义模型记录
            related_custom_records = self.env['your.custom.model.name'].search([
                ('partner_id', 'in', partner_id_list)
            ])
            # 遍历每个partner,给关联的自定义记录传对应的值(注意不要把partner的值错配)
            for partner in self:
                partner_linked_records = related_custom_records.filtered(lambda r: r.partner_id.id == partner.id)
                if partner_linked_records:
                    sync_payload = {
                        field: partner[field]
                        for field in SYNC_TARGET_FIELDS
                    }
                    partner_linked_records.write(sync_payload)
        return write_result

这个方案的优势:

  • 触发逻辑覆盖所有对res.partner的更新入口,不管是后台界面手动改、导入数据、接口对接修改,都能触发同步
  • 可以灵活加异常判断、日志记录,适配复杂业务规则
  • 只要自定义模型是通过partner_id关联res.partner的,不管是一对一还是一对多关系都能兼容

方案2:用Odoo内置服务器自动化动作实现,无需改代码

如果不想直接改Python代码、需要快速上线,可以用系统自带的自动化能力实现联动:

  • 进入「设置-技术-自动化-服务器动作」,新建动作
  • 触发模型选择res.partner,触发时机设为「当记录被更新时」,触发字段勾选你新增的两个Float字段
  • 动作类型选择「更新相关记录」,关联规则设置为「查找你的自定义模型中,partner_id等于当前被修改partner的所有记录」
  • 配置字段映射,把res.partner的两个Float字段值,同步到自定义模型的对应字段即可

这个方案适合临时需求、无代码环境的快速配置场景,缺点是复杂逻辑(比如加判断条件、异常通知)的灵活度比代码实现低。

常见误区提醒
很多技术资料提到的@api.depends跨模型依赖,从来没有设计成“跨模型反向监听独立字段变化触发计算”。它的所有触发逻辑,都严格围绕当前模型自身的字段访问链路展开,反向的跨模型同步从来不是这个装饰器的职责范围,不要在这上面继续绕弯路。

内容的提问来源于stack exchange,提问作者ITJ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 16:06:07