先说结论
Odoo 侧边栏里那些“动作”不是随便挂上去的。它们要同时满足几个条件:
- 动作本身绑定到了某个模型
- 当前用户有对应分组
- 当前用户能读目标模型
- 相关缓存已经刷新
所以你看到“动作明明建了,怎么没显示”,通常不是 UI 抽风,而是绑定链路有一环没过。
核心字段:binding_model_id、binding_type、binding_view_types
在 ir.actions.actions 里,binding_model_id 决定这个动作挂到哪个模型上。
binding_type = action:进入普通动作区binding_type = report:进入报表动作区binding_view_types:限制它在哪些视图类型里出现,比如list,form
这三个字段合在一起,才像是“把一个动作接到侧边栏上”。
Odoo 实际怎么取侧边栏动作
源码里最关键的是 get_bindings(model_name) 和 _get_bindings(model_name)。
大致链路是:
- 先从数据库里找出
binding_model_id = 当前模型的动作 - 再把这些动作按 concrete action 类型读出来
- 取出
name、binding_view_types、group_ids、res_model、sequence、domain - 转成缓存结果,供后续快速读取
这里有个很重要的点:它不是“查到一条记录就结束”,而是会把动作的可见性前置计算一遍。
为什么还要再过滤一次 group_ids 和读权限
_get_bindings() 负责把动作定义捞出来,get_bindings() 负责做最终用户过滤。
后者会继续检查:
- 这个动作有没有
group_ids - 当前用户是不是这些组里的成员
- 目标模型
res_model是否允许读
也就是说,动作绑定成功,不等于动作对所有人可见。
这也是很多人最容易误解的地方:
你以为自己是在配“菜单按钮”,其实 Odoo 还在背后跑权限过滤。
为什么创建、修改、删除后要清缓存
create()、write()、unlink() 里都调用了 self.env.registry.clear_cache()。
原因很直接:
- 绑定结果被缓存了
- 如果不清缓存,界面还会拿旧结果
- 新动作可能迟迟不出现,删掉的动作也可能“幽灵复活”一会儿
所以在动作绑定问题上,缓存不是细节,而是行为的一部分。
实战排查顺序
如果你怀疑一个动作没出现在侧边栏,建议按这个顺序看:
binding_model_id是否对binding_type和binding_view_types是否对group_ids是否挡住了当前用户- 目标模型是否真的可读
- 是否需要重启或至少清缓存后再看结果
最容易踩的坑
1)只配了 action,没有配绑定模型
这种动作存在,但不会自动出现在模型侧边栏。
2)只看管理员能不能看
管理员能看到,不代表普通用户也能看到。group_ids 和 model access 会继续筛掉一轮。
3)以为动作是静态菜单
不是。它更像“按模型动态生成的上下文入口”。
一句话总结
Odoo 的侧边栏动作,本质上是“模型绑定 + 用户权限 + 缓存结果”的组合产物。理解这条链路后,你就不会再把“动作不显示”简单归因成前端问题了。
DISCUSSION
评论区