先说结论
很多人觉得 Odoo domain 难,不是因为它真的多复杂,而是因为它看起来不像人平时写条件的方式。
但本质上,domain 只是在表达一件事:
我要从这批记录里筛出哪一部分。
你只要先抓住“筛选语义”,再看语法,domain 就会顺很多。
为什么 domain 老让人觉得像咒语
因为大家最常看到的写法像这样:
['|', ('name', 'ilike', kw), ('default_code', 'ilike', kw)]
或者更长:
['&', ('active', '=', True), '|', ('user_id', '=', user.id), ('team_id', 'in', team_ids)]
这类前缀写法和普通 Python and/or 很不一样,所以第一眼会非常不自然。
但你如果把它翻译成人话,它其实只是:
- 先做这层组合
- 再做那层组合
- 最后得到一个筛选集合
domain 本质上不是“代码技巧”,而是“过滤描述”
这是特别值得记的一点。
很多人学 domain 时,会把注意力全放在符号上。
其实更重要的是先想清楚:
- 我到底要保留哪些记录
- 哪些条件必须同时满足
- 哪些条件满足其一即可
如果业务过滤目标没想清楚,语法再熟也容易写错。
为什么默认 AND 容易被忽略
很多 domain 其实不用显式写 &,因为多个条件并列时,Odoo 默认就按 AND 处理。
这点很重要。
也就是说:
[('active', '=', True), ('company_id', '=', company.id)]
本质上已经是在说:
- active = True
- 并且 company_id = 当前公司
所以很多时候,真正让人乱的不是 AND,而是 OR 以及复杂嵌套。
为什么 OR 一多就开始晕
因为 OR 会把“满足任一条件就放行”这件事带进来。
而一旦 OR 和 AND 混着出现,你脑子里就必须先有分组。
所以写 domain 最稳的方法通常不是上来就敲,而是先写成人话:
- 必须是启用状态
- 并且要么属于我,要么属于我的团队
先把这句话想清楚,再翻成 domain,错误率会低很多。
前缀逻辑到底该怎么理解
最简单的办法不是背“前缀表达式”这几个字,而是记:
操作符写在它要组合的条件前面。
所以:
'|'表示后面两块条件取 OR'&'表示后面两块条件取 AND'!'表示后面一块条件取 NOT
你把它看成“先声明组合方式,再给出要组合的对象”,就没那么怪了。
为什么 domain 不只是 search 才会用
很多人一提 domain,就只想到 search()。
其实它在 Odoo 里出现得非常广:
- 列表过滤
- 字段候选范围
- record rule
- action 默认筛选
- relation 字段 domain
- 视图层选择限制
所以 domain 不是某个局部 API 技巧,而是 Odoo 里非常通用的“过滤语言”。
实战里最容易踩的 5 个坑
1. 业务过滤目标没想清楚就开始拼符号
最后很容易写出“能跑但不对”的条件。
2. OR 和 AND 分组没想清楚
这类问题最常见,也最难靠肉眼一眼看出。
3. 以为 domain 只影响搜索,不影响权限和候选范围
结果改一个地方,别处跟着变。
4. 条件太宽或太窄
用户会觉得“怎么什么都搜得到”或“怎么什么都没有”。
5. 不先写成人话
直接写符号最容易把自己绕进去。
一个特别实用的写法习惯
我很推荐这套顺序:
1. 先用中文写过滤目标
比如:只看启用记录,并且负责人是我或属于我的团队。
2. 先分层标出 AND / OR
先确定逻辑分组。
3. 最后再翻成 domain
这样可读性和正确率都会高很多。
一句话记忆法
把 domain 记成一句话:
domain 不是怪语法,而是 Odoo 用来描述“保留哪些记录、排除哪些记录”的统一过滤语言。
理解这一句,domain 就没那么像咒语了。
DISCUSSION
评论区