先说结论
在 Odoo 表单里,用户还没点保存时,系统里往往已经在围绕一条“临时对象”工作了。
这也是为什么你会遇到这种感觉:
- 记录明明还没落库
- 但 onchange、字段联动、表单逻辑却已经像在处理一条真实对象
这背后常见的关键词就是:
NewId_origin
为什么这个问题很容易把人绕晕
因为开发者脑子里常常有个默认前提:
- 先有数据库记录,后有对象逻辑
但 Odoo 表单交互并不完全按这个顺序。
为了让用户在“还没保存”时也能即时联动、预览、修改,系统往往会先构造一条临时记录语义来承接这些交互。
所以你看到的不是“数据库已存在对象”,而更像“表单工作态对象”。
NewId 更像什么
最通俗地说,它更像:
一张还没正式入库、但已经能在表单逻辑里被当作记录处理的临时身份。
它让系统可以先做很多事情:
- 表单联动
- 默认值计算
- onchange
- x2many 临时子项处理
但这不代表它已经是真正持久化的数据库记录。
_origin 为什么很关键
它通常特别有价值的地方在于:
当前这个表单中的临时/派生状态,原本是从哪条真实记录演化出来的。
这在编辑已有记录时尤其关键。
因为当前表单状态可能已经被用户改动过,
而 _origin 能帮你理解:
- 改动前原始记录是谁
- 某些比较、回退、联动到底该参考谁
所以它很像“当前工作态背后的原始出处”。
为什么 onchange 调试时特别容易遇到它们
因为 onchange 正发生在“用户还没正式保存”的阶段。
这意味着很多逻辑都运行在:
- 临时 recordset
- 变更中的表单状态
- 部分字段已改、部分还没真正持久化
所以如果你还拿“这就是数据库里那条最终记录”的脑回路去看,很容易判断错。
为什么这会影响你的调试判断
因为有些现象其实不是 bug,而只是阶段不同:
- 现在看到的是临时值
- 不是最终落库值
- 当前对象有
_origin - 不等于当前对象已经完全脱离原始记录
所以表单调试里,一个很重要的意识是:
- 先判断你现在面对的是持久记录,还是表单工作态记录。
实战里最容易踩的 5 个坑
1. 把 NewId 当成已经真实入库的记录
后面判断会偏。
2. 调试 onchange 时忘了当前记录仍处于临时状态
最容易误读现象。
3. 编辑已有记录时不理解 _origin 的意义
改前改后关系看不清。
4. 把表单工作态当成最终数据库事实
会把很多正常现象误判成 bug。
5. 只盯界面值,不判断当前对象所处阶段
定位效率会很低。
一句话记忆法
把它记成一句话:
NewId 像还没正式入库的临时记录身份,
_origin像当前表单工作态背后的原始真实记录;它们一起支撑了“未保存也能像对象一样交互”的表单体验。
理解这一句,很多表单调试问题会顺很多。
DISCUSSION
评论区