生命周期入口

Odoo create、write、copy 为什么总容易改炸:对象生命周期入口到底怎么分工

很多定制把 create、write、copy 逻辑一股脑堆进去,最后很难维护。本文讲清对象创建、修改、复制这几个入口到底各自该管什么。

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

先说结论

很多 Odoo 模型定制之所以越改越乱,不是因为不会 override,而是因为没想清楚:

  • 创建时该做什么
  • 修改时该做什么
  • 复制时又该做什么

create()write()copy() 看起来都像“对象发生了变化”,但它们代表的是完全不同的生命周期入口。

这几个入口如果不分工,后面非常容易:

  • 重复逻辑
  • 边界错位
  • 复制出脏数据
  • 修改时触发不该触发的动作

create() 真正关心的是什么

create() 最核心关心的是:

一条业务对象第一次进入系统时,应该如何建立。

它适合处理:

  • 初始字段补全
  • 新建时的基础校验
  • 首次生成某些关联对象
  • 建立对象出生时就该有的结构

也就是说,create 关心的是“出生逻辑”。


write() 真正关心的是什么

write() 更像:

已有对象被修改时,系统该怎样响应这次变更。

它适合处理:

  • 状态变化后的联动
  • 字段变更后的同步逻辑
  • 修改时的约束保护
  • 某些更新后的后续动作

所以 write 不是“create 的第二版”,它处理的是对象已经存在之后的变化。


copy() 为什么经常被低估

因为很多人会想:复制不就是创建一条新记录吗?

技术上它最终确实会变成新对象。

但业务语义完全不一样。

copy() 真正关心的是:

当一个对象被拿来当模板复用时,哪些值应该继承,哪些值必须重置,哪些业务痕迹绝不能带过去。

这和普通 create 差别很大。


为什么复制逻辑特别容易出脏数据

因为“复制可见字段”并不等于“复制业务语义”。

很多对象里会有这些东西:

  • 状态
  • 编号
  • 追踪记录
  • 已完成动作
  • 下游关联
  • 统计结果

这些内容如果跟着复制过去,往往会直接污染新对象。

所以 copy 的真正难点不是复制本身,而是:

  • 哪些该带,哪些不该带。

为什么很多逻辑不该同时塞进 create 和 write

因为它们的语境不一样。

有些事情只应该在对象第一次出生时发生; 有些事情只应该在后续更新时发生; 如果两个入口都塞,就可能变成:

  • 新建时重复触发
  • 修改时误触发初始化逻辑
  • 维护者根本看不懂真正边界

所以生命周期入口最重要的,不是 override 本身,而是边界感。


一个特别实用的判断方法

写逻辑前先问:

1. 这是对象“出生时”才该发生的吗?

如果是,更接近 create。

2. 这是“已有对象变化后”的响应吗?

如果是,更接近 write。

3. 这是“从旧对象派生新对象”时的继承策略吗?

如果是,更接近 copy。

只要先把这三件事分开,很多代码结构会自然清楚。


实战里最容易踩的 5 个坑

1. create 和 write 里放同一套逻辑

边界会越来越糊。

2. copy 不重置状态、编号、痕迹字段

最容易复制出脏数据。

3. 把“首次初始化”逻辑放进 write

后续更新会不断误触发。

4. 把“变更响应”逻辑只放 create

后来对象修改时行为不一致。

5. 只从技术复用角度写,不从业务生命周期角度写

这类代码一开始省事,后面最难维护。


一句话记忆法

把它们记成一句话:

create 管对象出生,write 管对象变化,copy 管对象派生;它们都在改数据,但负责的生命周期阶段完全不同。

理解这一句,Odoo 模型入口设计会清楚很多。

DISCUSSION

评论区

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