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)
数据库状态变化
- 初始状态(创建记录后,PSQL查询结果):
parent_id | parent_name ----------|------------- 1 | {'en_GB': 'open'}
- 西班牙语用户修改关联记录为
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
相关产品推荐
相关产品推荐

