默认值机制

Odoo 默认值为什么有时不听话:default_get、context、active_id 到底怎么配合

很多默认值问题看起来像玄学,其实大多都和 context、default_get、字段 default 的优先级有关。本文帮你一次理顺。

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

先说结论

Odoo 默认值问题,最容易乱的地方不是语法,而是:

  • 默认值从哪来
  • 谁优先
  • 当前 context 里到底带了什么

你只要先记住一句话:

Odoo 的默认值不是单点来源,而是字段定义、context、default_get 共同作用的结果。

很多“为什么没生效”就能立刻缩小范围。


为什么默认值经常像玄学

因为同一个字段的初始值,可能同时受到这些因素影响:

  • 字段 default=
  • context 里的 default_xxx
  • default_get() 里动态计算
  • 当前入口带进来的 active_model / active_id / active_ids

如果你没意识到它们是叠加关系,而是只盯着某一个点看,就会觉得系统好像不稳定。

实际上,大多数时候不是 Odoo 抽风,而是你漏看了另一个来源。


字段 default= 是最基础的一层

这是最容易理解的默认值来源。

它表达的是:

  • 如果没有别的更具体输入
  • 这个字段通常默认给什么

它适合:

  • 常量默认值
  • 跟当前用户或环境轻度相关的默认值
  • 比较稳定的初始行为

但它通常不适合非常依赖当前操作上下文的复杂默认逻辑。


context 里的 default_xxx 为什么这么常见

因为它很适合“从入口把意图带进来”。

比如你从某个按钮打开 wizard,可能就会带:

  • default_partner_id
  • default_company_id
  • default_move_type

这类默认值最像:

调用方在说:我希望打开表单时优先按这个来。

所以它特别适合:

  • 按钮打开表单
  • 不同入口打开同一模型
  • wizard 预填当前记录相关值

default_get() 真正适合什么

default_get() 最适合处理:

  • 多个字段需要联动决定默认值
  • 默认值依赖当前上下文
  • 需要按当前用户、公司、入口、选中记录综合判断

也就是说,它更像:

统一组装默认值的动态工厂。

如果只是给一个简单常量,没必要什么都塞进 default_get()

但如果逻辑开始有条件分支,它就很有价值。


active_id / active_ids 为什么老出现

因为很多默认值都不是凭空来的,而是从“用户刚刚正在操作的那批记录”推出来的。

比如:

  • 从销售单打开创建发票向导
  • 从一批记录打开批量操作向导
  • 从联系人页打开新建机会

这时 context 里往往会带:

  • active_model
  • active_id
  • active_ids

它们本质上是在告诉你:

这次默认值逻辑,应该围绕哪批源记录展开。


为什么有时你明明写了 default,却还是不生效

常见原因通常就这几类:

1. 被 default_xxx 覆盖了

入口 context 优先表达了更具体意图。

2. 被 default_get() 改掉了

你后面动态组装时覆盖了前面值。

3. 当前视图或入口根本没带你以为的 context

你以为有 active_id,其实没有。

4. 字段本身在 create 过程中又被 onchange / 逻辑重算

默认值生效过,但后来被新逻辑改掉。


一个特别实用的排查顺序

如果默认值不对,建议按这个顺序查:

1. 字段定义里有没有 default=

先看静态基础值。

2. 打开入口有没有传 context

尤其检查 default_xxx

3. default_get() 有没有覆盖

这是最常见的动态改写点。

4. active_model / active_id / active_ids 是否真存在

别按想象排查。

5. 后续 onchange 或 create 逻辑有没有再改值

很多人只查默认值阶段,忘了后面还有二次覆盖。


最稳的设计思路

我更推荐这样分工:

  • 简单稳定默认值 → 放字段 default=
  • 入口相关默认值 → 放 contextdefault_xxx
  • 复杂动态拼装 → 放 default_get()

这样层次清楚,后面你自己回来看也不容易晕。


一句话记忆法

把它记成一句话:

字段 default 给基础值,context 给入口意图,default_get 负责动态组装,active_id/active_ids 提供当前操作上下文。

理解这一句,Odoo 默认值问题基本就不再玄学。

DISCUSSION

评论区

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