先给答案
Odoo 权限不是“ACL 和记录规则二选一”,而是 先过 ACL,再过记录规则。
在 odoo/orm/models.py 的 _check_access() 里,顺序很明确:
- 先调用
ir.model.access检查模型级权限 - ACL 通过后,再去算
ir.rule的 domain - 如果当前记录不落在允许 domain 里,就仍然报权限错误
所以:
ACL 决定你有没有资格碰这个模型,记录规则决定你能碰这个模型里的哪些记录。
少任何一层,结论都会错。
第一层:ACL 先决定“你配不配进门”
源码里先做的是:
Access = self.env['ir.model.access']
if not Access.check(self._name, operation, raise_exception=False):
...
这一步只回答一个问题:
- 你对这个模型有没有
read/write/unlink这样的基本操作资格
它不关心你要读哪一条记录。
所以如果 ACL 没给:
- 你连这个模型的大门都进不去
- 后面的记录规则根本没机会救你
这是许多排错时的第一个误区: 有人看到写了规则,就以为规则会“放行”。 不会。 ACL 先卡死,规则根本不参与。
第二层:记录规则决定“进门后你能看到哪些记录”
ACL 通过后,源码会继续:
- 取
ir.rule - 计算当前模型、当前操作下的 domain
- 用
self.sudo().with_context(active_test=False).filtered_domain(domain)过滤允许记录 - 其余记录判定为 forbidden
这里最值得注意的一点是:
Odoo 在做记录规则判断时,核心不是“逐条 if else 写死”,而是:
先把规则合并成 domain,再拿 domain 去筛记录。
这解释了为什么很多权限问题本质上是 domain 问题,而不是“系统神秘抽风”。
最容易被忽略的一点:全局规则和组规则不是同一种叠加法
在 ir_rule.py 的 _compute_domain() 里,逻辑非常关键:
- 全局规则进入
global_domains - 有组的规则进入
group_domains - 最终结果是:
- 全局规则们 AND 在一起
- 分组规则们先 OR 在一起
- 再和全局规则整体 AND
把它翻成人话就是:
全局规则
像“所有人都必须满足的门禁”。
多个全局规则越加越严,因为是 AND。
组规则
像“你属于这些角色中的任一放行通道”。
多个组规则之间是 OR,不是 AND。
最终效果
你必须:
- 同时满足所有全局门禁
- 并且在自己所属组规则里至少命中一条放行通道
这正是很多人配置完权限后觉得“明明给了组规则,怎么还是被挡住”的原因。
因为真正挡住你的,可能是全局规则。
为什么会出现“列表里能看见,点进去却报权限错误”
这类问题很常见,但不一定是主记录本身的规则矛盾。
常见原因有三类:
1. 你能读主记录,但读不到关联记录
列表页只取少数字段,表单页会加载更多字段、关联模型、聊天记录、附件、统计信息。
于是:
- 主模型 ACL/规则没问题
- 但关联模型没有权限
- 结果打开详情时报错
2. 搜索场景和详情场景触发的上下文不同
规则 domain 可能和公司、上下文 key、活动记录过滤等有关。
3. 你看的不是同一层问题
有人以为“能搜到 = 一定可编辑”。
但 read、write、unlink 是不同操作,规则可以分别限制。
所以排这类问题时,别只盯一张截图。 要明确:
- 哪个模型
- 哪个操作
- 哪条记录
- 哪个关联字段在报错
过时接口名字为什么还会误导你
源码里 check_access_rights()、check_access_rule() 已经标成 deprecated,最终都汇到更统一的 check_access() / _check_access() 逻辑。
这件事提醒我们:
- 概念上还是 ACL + 规则两层
- 但排查时最好回到新主入口
_check_access()看真实顺序
否则你可能盯着老方法名理解,结果和现在的调用链对不上。
排权限问题,我一般按这个顺序
- 先确认模型 ACL 有没有给到对应操作
- 再确认当前用户属于哪些组
- 看有没有全局规则在收紧范围
- 再看组规则有没有放行路径
- 如果是“列表能看、详情报错”,继续检查关联模型权限
- 最后才去怀疑是不是缓存或界面问题
大多数权限 bug,到第 4 步其实就已经定位了。
最后一句话
Odoo 权限的核心不是“有没有写规则”,而是你要同时想清楚三件事:
- 模型级操作资格在不在
- 记录级 domain 怎么算
- 全局规则和组规则到底是 AND 还是 OR
把这三层理顺后,权限问题会从“玄学报错”变回一套很工整的布尔逻辑。
DISCUSSION
评论区