x2many 命令

Odoo One2many / Many2many 命令别硬背了:一文讲清 x2many Commands 的真实含义

(0, 0, values)、(4, id)、(6, 0, ids) 这些命令很多人背了又忘。本文不靠死记硬背,而是帮你真正理解 Odoo x2many 命令在表达什么。

Odoo 开发
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说最重要的事

很多人学 Odoo x2many 字段时,最痛苦的不是不会写代码,而是:

  • tuple 太像咒语
  • 不同命令老是混
  • 能运行,但不确定是不是写对了

其实这些命令并不神秘。

你只要把它们理解成:

“我想怎么改一组关联记录”

很多事情就通了。


为什么 x2many 不能像普通字段那样直接赋值

因为 x2many 不是单值。

它表示的是“一组关系”或“一组子记录”。

所以系统必须知道的,不只是“新值是什么”,还包括:

  • 是要新增一条?
  • 是要更新现有一条?
  • 是要删掉关联?
  • 是要替换整组?
  • 是要清空全部?

这就是 commands 存在的原因。

它们本质上不是怪语法,而是关系操作指令


最好用的脑内模型

把 x2many command 理解成:

  • create:新增一条子记录
  • update:更新已有记录
  • delete/unlink:去掉某条记录或关系
  • clear:清空整组
  • replace:用一整组新 id 替换旧集合

只要你先在脑子里想清楚自己要做的是哪类动作,再回头看命令,就不会那么乱。


(0, 0, values):新增

这个最常见。

它表达的是:

  • 创建一条新记录
  • 并把它挂到当前 x2many 字段里

所以它很适合:

  • 给订单新增一条 line
  • 给凭证新增一条分录
  • 给向导一次性补几条临时子项

它不是“引用已有记录”,而是“现场新建”。


(1, id, values):更新已有记录

这表示:

  • 找到已有记录 id
  • values 更新它

这个命令特别适合你已经知道子记录存在,只想改其中几个字段的场景。

常见误区是:

  • 想新增却用了 1
  • 想整体替换却拿 1 循环瞎改

所以在用它之前先问自己一句:

这条子记录是不是已经真实存在?


(2, id)(3, id) 为什么老让人混

因为它们都像“删”。

但语义并不一样。

你可以先用人话去理解:

  • (2, id):把这条记录本身删掉
  • (3, id):把这条关联断开

对于具体字段类型和关系场景,效果会受到模型关系约束影响,但大方向上,这个区分非常重要。

所以不要把它们都粗暴地理解成“移除一下”。

有时你想断关系,结果把底层记录真的删了,这就很危险。


(4, id):挂接一条已有记录

这个命令的语义最像:

这条记录已经存在了,把它关联进来。

它不是创建。

所以适合 Many2many 场景尤其多,比如:

  • 给用户补一个已有标签
  • 给某对象关联已有分类
  • 把现成记录加进集合

如果你脑子里想到的是“加进来,但不要新建”,那大概率就是它。


(5, 0, 0):清空整组

这是最暴力也最清楚的一个。

意思就是:

  • 当前这组关联先全部清空

它适合“我不要旧集合了”的场景。

但也正因为太干脆,使用时要特别小心。

尤其在批量更新里,一旦用错,就会把整组关系都抹掉。


(6, 0, ids):整组替换

这是实战中非常常用的一条。

它的意思不是“追加这些 id”,而是:

  • ids 这整组结果
  • 直接替换当前字段原来的整组内容

所以它很适合:

  • 表单提交后的最终同步
  • 多选框完整回写
  • “现在这一组应该准确等于这些记录”

最常见误区是把它当追加用。

如果你只是想补几条关系,却用了 (6, 0, ids),你可能会把没列出来的旧关系全覆盖掉。


Odoo 新版 Command API 为什么更推荐

近年的 Odoo 版本更推荐用 Command.create(...)Command.update(...) 这类写法。

原因很简单:

  • 可读性更高
  • 不容易把数字命令写混
  • 对团队协作更友好

也就是说,tuple 命令不是不能用,而是:

人脑更适合读语义,不适合长期背数字。

如果项目版本允许,我也更推荐用 Command API。


实战里最容易踩的 5 个坑

1. 把 (6, 0, ids) 当追加

结果旧关系被整组覆盖。

2. 该新建时用了 (4, id)

但实际上那条记录根本还不存在。

3. 该断关系时用了会删除底层记录的命令

这类问题非常危险。

4. 循环里乱拼 commands,没先想清最终目标集合

代码能跑,但逻辑容易脏。

5. 只会背数字,不理解动作语义

换个场景立刻又乱。


一套特别好用的记忆方法

不要背数字,先背动作:

  • 新建
  • 更新
  • 删除/断开
  • 挂接已有
  • 清空
  • 整组替换

然后再去映射具体 command。

只要动作先清楚,写法就不容易错。


一句话记忆法

把 x2many commands 记成一句话:

它们不是奇怪的 tuple,而是在告诉 Odoo:我想如何增删改一整组关联记录。

理解这一句,就不需要再靠死记硬背了。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。