跳至内容

Odoo 中的 Domain 字段详解:概念、用法与示例

讲清楚 Odoo 中的 Domain 字段类型到底是啥、会在什么地方出现,以及如何在数据模型和个性化定制中合理使用它。先把它当成一种“筛选规则”:不是单纯存数据的字段,而是用于描述记录筛选条件的结构——可以把它看作一段可复用的查询表达式。你会在模型定义、字段约束、视图过滤、关联字段和自动化逻辑(如服务器动作、计算字段、默认值)里遇到它。掌握它的语法(比较运算、逻辑组合、动态变量占位)与常见用法(静态条件、基于上下文或用户动态生成的条件、跨关联字段的过滤)能让你在设计关系、限制可选记录、提高数据一致性和优化界面交互时更得心应手。文中会重点提示调试方法、性能注意点以及如何在定制模块中优雅地构造和复用 Domain,使你的 Odoo 模型既安全又高效。
2026年3月6日
Odoo 中的 Domain 字段详解:概念、用法与示例
Dasolo
| 还没有评论

在配置 Odoo 时,你很可能见过那种用方括号和条件写成的“过滤表达式”。这些表达式不仅出现在动作按钮和自动化规则里,也常见于记录规则与邮件模板中。少有人注意到,Odoo 的 ORM 实际上提供了一种专门的字段类型:Domain 字段,用来以结构化的方式存储和展示这些过滤条件,而不是把它们当纯文本对待。


无论你是编写自定义模块的开发者,还是在后台配置业务流程的管理员,理解域字段都很重要。本文将从域字段保存什么、如何在界面中使用、开发与调试技巧,到常见错误及其规避方法一并讲清楚,帮助你更自信地把筛选逻辑放到模型里管理。

什么是 Odoo 中的 Domain 字段(域字段)


在 Odoo 中,“domain”指的是用于查询记录的一组过滤条件。它有固定的语法——以元组为单位并可能包含逻辑运算符——在执行数据库查询时直接映射为 SQL 的 WHERE 子句。

典型的 domain 表达式示例


[('customer_rank', '>', 0), ('active', '=', True)]

含义是:返回所有 customer_rank 大于 0 且 active 为 True 的记录。


fields.Domain(域字段)是 Odoo ORM 提供的一种字段类型,用来把上述过滤表达式作为结构化数据保存到记录里。与普通文本字段不同,它自带校验逻辑并在界面上有专用编辑器,允许业务人员通过可视化方式构建筛选条件,而无需直接写表达式。


在界面中的呈现方式

在前端,Domain 字段通常由域编辑器(domain widget)渲染。该编辑器以可视化规则构建器的形式出现,用户可以选字段、选运算符(等于、包含、大于等)并填写值;这与配置访问规则或自动化动作时看到的界面一致。


在数据库层面,域的值以文本形式存储——实际上是 Python 列表的字符串表示。字段类型会负责序列化与校验,开发者在 Python 代码里处理的是结构化的域数据,而存储层负责把它转换成字符串。

这也体现了 Odoo 的数据模型设计理念:字段不仅是存储单元,还携带语义、UI 行为与验证规则,一处定义胜过多处约定。

字段如何工作


域字段与 ORM、记录过滤系统的结合非常紧密。保存与评估域时,后台会发生一系列处理,下面逐步说明。


存储与表示

写入数据库时,Odoo 会把域序列化为字符串保存。很多域依赖运行时变量,比如限制为当前用户草稿的条件会在查询时解析 uid 为当前用户 ID,从而实现动态过滤而不需硬编码具体数值。

执行查询前,ORM 会通过 Odoo 的安全求值机制(safe_eval)把字符串表达式解析为可执行的过滤结构,随后转换为相应的 SQL WHERE 子句。safe_eval 支持受控的 Python 子集并能识别 Odoo 特定的上下文变量。


域编辑器(domain widget)

在界面里,fields.Domain 类型默认用域编辑器呈现。用户可以在该编辑器内添加条件,用 AND/OR 组合规则,并实时预览结果,无需直接操作表达式文本。

正是这个可视化工具让非开发人员也能配置复杂筛选;他们不必掌握 domain 语法,界面会替他们完成翻译与验证。


模型上下文

一个域字段通常与某个模型关联,这样域编辑器才能知道应该显示哪些字段供用户选择,这通过字段定义里的 model_field 属性来指定。若没有模型上下文,编辑器会退化为纯文本输入,对终端用户帮助有限。


这种上下文绑定是 Odoo 框架将字段定义与 UI 行为关联起来的关键一环:字段“知道”它针对哪个模型,界面据此调整可选项与校验逻辑。


与其它记录的交互

域字段常与关系型字段配合使用:它可以约束 Many2one 下拉里显示哪些记录、限定自动化动作的目标范围,或定义报表/仪表盘的数据范围。因为过滤在 ORM 层生效,它会遵循 Odoo 的权限和字段访问控制。

业务场景举例


域字段几乎出现在所有 Odoo 模块里。下面列举五个常见的业务应用场景,说明它们如何推动实际流程。


1. 自动化动作与邮件触发

在设置自动化动作(Settings > Technical > Automation)时,通常在动作上定义一个域来限定触发记录。例如,针对逾期发票的自动邮件可以只针对已过期且未付款的已过账发票。这个域保存在 base.automation 模型的 filter_domain 域字段上,只有匹配的记录才会触发动作。


2. 记录规则与访问控制

安全记录规则通过域字段限制某用户组可见或可编辑的记录范围。比如销售团队可能只能看到分配给其团队的记录,这种基于域的行级安全无需编写额外代码。Odoo 中每条记录规则的过滤条件本质上就是存储在域字段里的表达式。


3. 仓储与运营筛选

在仓库与库存管理中,计划动作和补货规则用域来锁定特定品类、仓位或库存水平。比如自动补货可只针对可存储且库存低于补货点的产品,从而避免对海量记录进行无谓处理。


4. CRM 管道与线索分配

在 CRM 模块中,阶段自动化、活动规则与线索分配都依赖域来对线索进行归类与筛选。自定义线索分配规则可根据国家、行业或合同规模匹配合适的销售人员,域字段让这些规则能从界面上配置,而无需每次都改代码。


5. 动态 Many2one 下拉

在自定义表单里,对 Many2one 字段应用域可以控制下拉显示的记录。比如把供应商字段限制为仅显示活跃且供应商评分非 0 的记录,会提升录入准确性。域还能引用同表单上其他字段,使下拉选项随用户选择动态变化。

创建与定制域字段


在实际操作中,有两类方式可以定义或使用域字段:借助 Odoo Studio 的无代码配置,或在定制模块中用 Python 和 XML 编写。


使用 Odoo Studio

Odoo Studio 的可视化字段创建器并不直接暴露一个独立的 Domain 字段类型。但通常不需要,因为 Odoo 自带的自动化动作、记录规则等处的域编辑器已经足够大多数业务配置需求。

如果你想在表单上为某个 Many2one 添加过滤器,可以在 Studio 中编辑该字段属性并直接填写域表达式;Studio 会校验语法并把域保存到视图定义上。


在 Python 中进行技术定制

在自定义模块里加入 Domain 字段是常见且直接的操作,符合 Odoo 官方开发流程。下面是一个基本的 ORM 示例:

from odoo import models, fields

class MyModel(models.Model):
    _name = 'my.model'

    model_name = fields.Char(default='res.partner')
    filter_domain = fields.Domain(
        string='Filter Domain',
        model_field='model_name',
        help='Domain expression to filter partner records'
    )

这里的 model_field 属性把域编辑器和储存模型名的字段(model_name)关联起来,让编辑器知道应展示哪些字段供选择。将模型名独立成字段也便于在运行时动态切换目标模型。


在表单视图中显示域编辑器

要在表单视图中呈现域构建器,需要在视图 XML 里同时引用模型字段与域字段,示例如下:


<field name="model_name" invisible="1"/>
<field name="filter_domain" widget="domain"
       options="{'model': 'model_name'}"/>

如果没有声明 widget="domain" 且不提供 model 选项,字段会以纯文本方式显示。要让用户看到可视化构建器,务必同时包含这两项。


通过 XML-RPC API 写入域值

如果你通过 API 程序化设置域字段值,务必以字符串形式传递值:

models.execute_kw(db, uid, api_key, 'my.model', 'write',
    [[record_id], {
        'filter_domain': "[('active', '=', True)]"
    }]
)

直接传入 Python 列表而非字符串是常见错误,会在不同 Odoo 版本中导致类型错误或静默失败。通过 API 写入前请务必先序列化为字符串。

最佳实践


遵循这些实用习惯能在处理域字段时避免不少麻烦。


部署前校验域语法

无效的域会在 Odoo 尝试解析或应用时立刻抛错。部署到自动化动作或记录规则前,应在搜索栏或开发者模式下测试域,或者通过 API 调用 search_count 来确认域返回的记录数符合预期。


尽量使用动态变量

避免在域中硬编码用户 ID、公司 ID 或固定日期。应使用 uidcontext_today()current_company_id 等动态变量,让域在不同环境下依然可用,减少在迁移或复制配置时出现的隐性故障。


始终绑定模型上下文

在自定义模型中添加 Domain 字段时,务必设置 model_field 并在视图中包含该字段。缺少模型引用会让用户看到普通文本输入框,而非友好的可视化构建器,进而增加保存无效域的风险。


保持域可读性

复杂的嵌套域(使用 |&)很容易变得难以维护。为复杂域在 Python 代码中添加注释说明意图;若域过于臃肿,评估是否用服务器动作或计算字段替代,以提高可测性与可维护性。


在程序中用 safe_eval

在 Python 代码中评估域字符串时(例如服务器动作或自动化动作里),应使用 Odoo 的 safe_eval 而不是原生 eval。safe_eval 更安全,能正确处理 Odoo 特有的上下文变量,并与平台内部的解析机制保持一致。


用真实数据测试

在上线前务必用接近现实的数据验证域是否返回目标记录。对自动化动作和记录规则尤其重要:错误的过滤可能导致错误记录被处理或用户被无故禁止访问,而系统不会弹出明显警告。

常见陷阱


下面列出与域字段相关的常见错误,以及如何避免它们。


把字段类型和域语法混为一谈

在 Odoo 里,“domain”有两层含义:一是指过滤语法(元组列表),二是指 ORM 的 fields.Domain 类型。很多刚接触定制的人会混淆:Domain 字段是用来存储表达式的数据容器,而域表达式本身才是过滤逻辑。弄清两者角色有助于避免设计与实现上的错误。


通过 API 传入列表而不是字符串

通过 XML-RPC 写入 Domain 字段时必须传字符串,传入原生列表会导致错误或静默失败。写入前务必把域序列化为字符串。


在 widget 中未指定模型上下文

把 Domain 字段放到视图里却没有在 widget options 里指定模型,会让用户看到普通文本输入而不是可视化构建器。域构建器只有在能识别目标模型时才会出现;视图定义里一定要包含 model_field 的关联。


在域中硬编码记录 ID

直接在域里写死记录 ID 会在目标记录被删除或把配置迁移到新库时悄然失效。尽量用像 uid 这样的动态引用或关系查找来保持域的可移植性。


记录规则域过宽或过严

一个过于宽松的记录规则会让不该看到记录的人看到数据;过严则会让用户看不到本应可见的记录。测试记录规则时应以目标用户组的视角进行,而不是用拥有全权限的管理员账号来测试。


忽视已归档记录

默认情况下 Odoo 在搜索结果里排除已归档记录(active = False)。如果你的域未考虑到这一点,可能会出现数据缺口。需要包括归档记录时,可加上 ('active', 'in', [True, False])

总结


域字段是 Odoo 中推动记录过滤逻辑的基础组件之一。从访问控制、自动化动作到动态下拉和仪表盘筛选,域表达式无处不在;而 fields.Domain 类型则为开发者提供了在数据模型中以经过校验的方式保存这些逻辑的手段。


对于业务用户,域编辑器把复杂的筛选配置变成零代码的操作;对于开发者,Domain 字段把原先靠通用 Char 字段与 widget 覆盖实现的逻辑变得更清晰、可维护。无论你在用 Odoo Studio、编写自定义模块,还是从界面配置自动化规则,掌握域字段都会让你能做更多事情且更可靠。


本指南中的概念适用于多个 Odoo 版本与模块。花时间理解域字段是值得的,因为它们在系统中无处不在,是许多关键功能背后的核心。


需要 Odoo 实施支持?

Dasolo 帮助企业实施、定制并优化 Odoo,使其契合具体业务需求。无论是配置自动化流程、开发自定义模块,还是提升现有 Odoo 系统的价值,我们的团队都具备推动项目向前的技术深度与实战经验。

如果你对域字段或 Odoo 实施的其他方面有疑问, 请联系我们,我们很乐意审阅你的系统设置并为你指明合适的改进方向。

Odoo 中的 Domain 字段详解:概念、用法与示例
Dasolo 2026年3月6日
分析这篇文章
登录 留下评论