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

Odoo关联翻译字段值变更后旧术语留存数据库问题

Odoo存储型关联翻译字段更新异常:旧语言术语未被同步覆盖

问题现象

在Odoo中,当使用存储型关联字段关联到translate=True的字段时,从表单修改关联记录后,仅会更新当前用户语言的翻译术语,旧语言的术语会残留在数据库中,导致不同语言用户看到不一致的内容。

示例模型代码

class Main(models.Model):
    name = fields.Char(translate=True)

class Child(models.Model):
    parent_id = fields.Many2one('main')
    parent_name = fields.Char(related='parent_id.name', store=True)

数据库状态变化

  1. 初始状态(创建记录后,PSQL查询结果):
parent_id | parent_name
----------|-------------
1         |  {'en_GB': 'open'}
  1. 西班牙语用户修改关联记录为parent_id=2(对应英文名称为"won",西班牙语为"Ganado")后,数据库状态变为:
parent_id | parent_name
----------|-------------
2         | {'en_GB': 'open', 'es_ES': 'ganado'}

此时英文用户查看仍显示旧值"open",仅西班牙语用户看到正确的"ganado"。

问题原因

调试发现Odoo执行的更新SQL语句为:

UPDATE "child" SET "parent_name" = '{"en_GB": "won"}' || COALESCE("parent_name", '{}'::jsonb) || '{"es_ES": "ganado"}'

其中COALESCE("parent_name", '{}'::jsonb)会保留原字段中已存在的翻译条目,导致旧语言的术语没有被新关联记录的对应语言翻译覆盖。

解决方案

方式1:重写关联字段的写入逻辑

继承Child模型,重写写入方法,强制使用新关联记录的完整翻译值覆盖旧值,而非合并:

class Child(models.Model):
    _inherit = 'child'

    @api.model
    def write(self, vals):
        if 'parent_id' in vals:
            parent_rec = self.env['main'].browse(vals['parent_id'])
            # 获取关联记录name字段的完整翻译JSON
            full_translation = parent_rec.with_context(lang=None).name
            vals['parent_name'] = full_translation
        return super(Child, self).write(vals)

方式2:使用计算字段替代关联字段

将parent_name改为计算字段,每次读取时直接从关联记录获取最新翻译值,避免存储带来的同步问题:

class Child(models.Model):
    parent_id = fields.Many2one('main')
    parent_name = fields.Char(compute='_compute_parent_name')

    @api.depends('parent_id.name')
    def _compute_parent_name(self):
        for rec in self:
            rec.parent_name = rec.parent_id.name

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 15:03:21