菜单与动作

Odoo 菜单点下去到底发生了什么:ir.actions.act_window、菜单与视图打开链路讲透

很多人会配菜单,但不真正理解菜单、Window Action、视图和上下文是怎样串起来的。本文把用户点一下菜单后背后的链路讲清楚。

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

先说结论

在 Odoo 里,用户点一个菜单,并不是“页面直接打开某个模型”。

更准确地说,中间通常隔着一层动作对象,最常见的就是:

  • 菜单 menuitem
  • Window Action ir.actions.act_window
  • 视图模式 view_mode
  • domain / context
  • 最终打开具体列表、表单、看板或搜索结果

所以菜单更像入口,真正决定“打开什么、怎么打开”的核心,往往是 action。


为什么很多菜单问题其实不是菜单问题

因为用户表面看到的是“我点了左边菜单”。

但真正影响结果的常常是:

  • action 绑的是哪个模型
  • 默认打开列表还是表单
  • domain 有没有过滤
  • context 有没有默认值
  • 指定视图有没有优先级冲突

所以很多“菜单打开不对”的问题,本质上应该去看 ir.actions.act_window,而不只是盯着 XML 里的 menuitem。


ir.actions.act_window 本质上是什么

它最适合理解成:

告诉客户端:请用什么方式打开这类记录。

它常常决定这些事情:

  • 打开哪个模型
  • 可用哪些视图模式
  • 默认先落在哪个视图
  • 是否带默认 domain
  • 是否带 context
  • 是否限制某个 search view

所以它并不是“一个小跳转配置”,而是用户进入一个业务对象页面时的主要入口协议。


菜单为什么通常只是 action 的外壳

菜单本身更多是导航结构。

它负责:

  • 把入口放到左侧导航里
  • 组织层级
  • 控制可见性和归属位置

但菜单通常不应该承担太多打开逻辑。

真正的“业务入口定义”更应该放在 action 里。

这也是为什么很多时候一个 action 可以被:

  • 菜单复用
  • 按钮复用
  • Python 返回值复用

而菜单只是其中一个触发点。


view_mode 为什么这么关键

很多人只记得写个 tree,form,但没真正意识到它在表达什么。

它本质上是在告诉客户端:

  • 这个入口允许用户用哪些视图看数据
  • 默认先从哪类视图开始

所以像:

  • tree,form
  • kanban,form
  • calendar,tree,form

不只是语法差异,而是在设计用户进来之后的第一体验。

如果入口目标是“先浏览一批记录”,通常列表/看板优先; 如果入口目标是“直接处理单条对象”,有时表单就更合适。


domain 和 context 为什么经常一起出现

因为它们解决的是两类不同问题:

  • domain:这次主要看哪些记录
  • context:这次打开页面时带什么默认意图

你可以把它们理解成:

  • domain = 看什么
  • context = 怎么带着前提去看

比如同样打开销售订单:

  • 一个 action 只看报价单
  • 一个 action 只看销售订单
  • 一个 action 默认新建时带某种单据类型

看起来都像“打开 sale.order”,但入口体验其实完全不同。


为什么一个模型会有很多不同的 action

因为同一个模型可以承载很多业务入口。

例如同一个对象可能同时需要:

  • 全量管理入口
  • 我的待处理入口
  • 某状态筛选入口
  • 从某模块跳转过来的专用入口

如果你把所有入口都挤进一个 action,再靠用户自己切筛选,体验通常不会太好。

所以多个 action 并不是重复劳动,而往往是在表达不同业务入口语义。


实战里最容易踩的坑

1. 菜单绑对了,但 action 模型错了

结果页面能开,但内容完全不对。

2. view_mode 配了,但首屏体验不合适

用户一进来就觉得别扭。

3. domain 过重,导致入口看起来“丢数据”

其实是被过滤了。

4. context 里塞太多默认值

后面 create / 搜索 / 切换入口时容易混乱。

5. 同一个入口目标,却复制很多相似 action

维护会越来越散。


一套很实用的设计顺序

设计菜单入口时,我更建议按这个顺序思考:

1. 用户点这个入口,第一眼应该看到什么

先定列表、看板、表单还是日历。

2. 这批用户应该默认看哪类记录

再决定 domain。

3. 新建时是否需要携带明确上下文

再决定 context。

4. 这是全局入口还是某业务场景专用入口

再决定要不要拆成多个 action。


一句话记忆法

把这条链记成一句话:

菜单负责把入口摆出来,ir.actions.act_window 负责定义“打开哪个模型、用什么视图、带什么过滤和上下文”。

理解这一句,Odoo 菜单与页面打开链路会清楚很多。

DISCUSSION

评论区

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