模型继承

Odoo _inherit 和 _inherits 到底差在哪:模型扩展与组合继承别再混了

很多 Odoo 开发会用 _inherit,但一遇到 _inherits 就开始混。本文把“扩展原模型”和“借别的模型当身体部件”这两种思路一次讲清。

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

先说结论

很多人第一次看到 _inherit_inherits,会以为只是拼写差一个字母。

其实它们代表的是两种完全不同的建模思路:

  • _inherit:在原模型上继续扩展
  • _inherits:把别的模型当成组成部件,通过组合暴露字段

也就是说,一个更像“在原房子上加层”,另一个更像“把隔壁房子的功能接进来”。


为什么这两个概念特别容易混

因为表面现象都像“我想复用别的模型能力”。

但问题在于,复用能力可以走两条路:

  • 直接扩展原对象
  • 让新对象组合引用另一个对象

如果你没先想清楚自己是在“扩展谁”还是“组合谁”,后面模型结构会越写越乱。


_inherit 真正在做什么

_inherit 最核心的含义是:

我还是这个模型,只是在它原有基础上继续加字段、加方法、改行为。

所以它特别适合:

  • 给现有模型补字段
  • 覆盖某个方法逻辑
  • 给现有对象增强能力

这时对象身份并没变,还是同一个模型,只是变得更强了。


_inherits 真正在做什么

_inherits 更像:

我创建一个新模型,但它借用了另一个模型的字段和部分身份能力。

这里的重点不是“改原模型”,而是“新模型通过外键把别的模型接进来”。

所以它更接近组合,而不是传统意义上的类继承。

这也是为什么它常让人一开始觉得绕。


为什么 _inherits 不该被当成“高级版 _inherit

因为它们不是强弱关系,而是建模方向不同。

如果你只是想扩展原模型,用 _inherit 往往最自然; 如果你需要的是:

  • 一个新对象
  • 但又想复用另一个对象的一整块字段结构

_inherits 才可能合适。

所以不是“会 _inherits 比较高级”,而是:

先看你的模型边界到底是不是新对象。


为什么 _inherits 后面更容易出现维护复杂度

因为它会把模型关系拉深。

你不仅要理解当前模型,还要理解:

  • 它依赖哪个父对象
  • 字段实际源头在哪
  • 删除时关系怎么处理
  • 创建时要不要连带创建父对象

这就意味着 _inherits 虽然强,但也更容易让维护者迷路。

如果业务上并不真的需要“组合出一个新对象”,那它反而可能把简单问题做复杂。


一个特别实用的判断方法

设计模型时先问:

1. 我是不是还在处理原来的那个业务对象?

如果是,优先想 _inherit

2. 我是不是要定义一个新的业务对象,只是它想借用另一模型的字段骨架?

如果是,才考虑 _inherits

3. 我是真的需要组合,还是只是想偷懒复用字段?

如果只是后者,要特别小心别把模型设计搞重了。


实战里最容易踩的 5 个坑

1. 本来只是扩展原模型,却硬上 _inherits

模型结构会变重。

2. 用了 _inherits,却没想清字段真正来源

后面排查会很痛。

3. 把 _inherits 当成普通继承理解

容易误判对象边界。

4. 创建/删除时没想好父子对象联动

很容易出数据一致性问题。

5. 为了少写字段就滥用组合

后面维护成本会更高。


一句话记忆法

把它们记成一句话:

_inherit 是扩展原模型,_inherits 是新模型组合借用别的模型结构;一个偏增强原对象,一个偏拼装新对象。

理解这一句,这两个继承机制就不容易再看混。

DISCUSSION

评论区

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