先说结论
如果普通 models.Model 像“正式档案”,那 TransientModel 更像“临时工作台”。
它适合做:
- 一次性确认弹窗
- 批量操作向导
- 导入前参数收集
- 短流程交互
但它不适合做长期业务数据沉淀。
很多人会用 wizard,却没真正理解它为什么叫 Transient。这正是后面踩坑的根源。
为什么 Odoo 要单独提供 TransientModel
因为系统里有很多交互,并不值得建成长期业务对象。
比如:
- “你确定要执行这次批量更新吗?”
- “请选择导入范围和日期区间”
- “为这批记录生成发票前,请先填几个参数”
这些信息往往只在当前操作瞬间有价值。
如果全都建成永久表,数据库会很快堆满“操作过程中的临时痕迹”。
所以 Odoo 提供 TransientModel,就是为了把:
流程交互数据
和
长期业务主数据
明确分开。
Wizard 本质上解决的不是“弹窗”,而是“短生命周期状态管理”
很多人把 wizard 理解成“弹窗 UI”。
这不够准确。
真正重要的是:
- 用户当前要完成一个短流程
- 这个流程需要临时保存几步输入
- 这些输入在流程结束后通常不再需要长期保留
所以 wizard 真正解决的是:
临时状态如何被安全、清晰地托管。
弹窗只是最常见的表现形式。
TransientModel 和普通 Model 最大差别是什么
最核心的区别不是字段写法,而是生命周期预期。
普通 Model 默认代表长期存在的业务事实。
TransientModel 默认代表:
- 为当前交互服务
- 可以被系统清理
- 不应该承担长期业务主档角色
这会直接影响你的设计判断。
如果一份数据需要长期查询、审计、统计、被其他流程引用,那大概率就不该只放在 TransientModel 里。
为什么很多 wizard 最终都要“把结果写回正式模型”
因为向导只是交互层,不是最终业务归宿。
典型链路是:
- 用户打开 wizard
- 在
TransientModel填临时参数 - 点确认按钮
- 向导方法去调用正式模型上的业务逻辑
- 正式结果写入
sale.order、stock.picking、account.move等持久模型
所以经验上要记住:
Wizard 负责收集决策,正式模型负责承载结果。
如果你把这两层混了,后面维护会非常痛苦。
为什么很多人会把 wizard 写得越来越重
因为向导开发起来很快。
于是容易一路加需求:
- 再多几个字段
- 再多几个按钮
- 再加一步确认
- 再挂点统计逻辑
- 再临时记个结果
最后就变成:
- 表面是弹窗
- 实际在里面偷偷塞了半个业务模块
这时问题就来了:
- 数据难审计
- 状态难追踪
- 权限容易混乱
- 清理机制和持久需求互相打架
所以 wizard 最怕的不是“不够强”,而是“被你当正式业务模型滥用”。
Wizard 按钮为什么常常是整个流程的真正入口
在 Odoo 里,wizard 上的按钮通常会触发 Python 方法。
比如:
- 批量确认
- 批量生成
- 应用参数
- 跳转目标记录
从技术上看,向导按钮经常才是“这次操作真正提交”的瞬间。
这意味着你在设计 wizard 时,不能只想表单长什么样,还要想:
- 触发后调用谁
- 是否需要校验
- 是否需要权限控制
- 出错时怎么反馈
- 结果写到哪里
为什么 default_get、context、active_ids 在 wizard 里特别常见
因为向导几乎总是依附于“当前用户正在处理的那批记录”。
所以它经常需要从上下文拿信息:
- 当前模型是谁
- 当前点选了哪些记录
- 默认值应该怎么预填
- 这次操作由哪个入口打开
于是你在 wizard 开发里会特别频繁看到:
self.env.contextactive_modelactive_idactive_idsdefault_get
这些并不是“魔法写法”,而是临时流程绑定当前操作上下文的自然方式。
实战里最容易踩的 5 个坑
1. 把长期业务数据存在 TransientModel
这样迟早会出问题,因为它天生不是给长期沉淀用的。
2. 业务核心逻辑全塞在 wizard 里
结果正式模型越来越空,维护边界越来越乱。
3. 过度依赖 context,却不清楚入口假设
不同入口打开 wizard 时,context 可能完全不一样。
4. 没想清楚按钮执行后的错误反馈
用户会觉得“弹窗点了没反应”。
5. 忽略权限和批量场景
向导常常是批处理入口,越是方便的东西,越要小心安全边界。
一套实用设计原则
如果你要写一个好的 wizard,建议记住这几条:
1. 向导只管收集短期参数
别让它背长期业务包袱。
2. 核心业务规则尽量放回正式模型
这样后续 API、自动化、测试都更稳。
3. 明确输入、动作、结果三层
输入在 wizard,动作在方法,结果在持久模型。
4. 提前设计好多记录批量执行场景
不要只按单记录思维写。
5. 把 wizard 当流程协调器,而不是数据库归宿
这个心智模型很重要。
一句话记忆法
把 wizard 记成一句话:
TransientModel最适合承载短流程交互状态,真正长期有效的业务结果应该回写到正式模型。
理解这句,很多 Odoo 向导设计问题都会变清楚。
DISCUSSION
评论区