简介
在 Odoo 中,‘模型’决定了业务数据如何被组织并存入数据库。无论是客户档案、销售订单还是发票,每一类核心数据都有对应的模型来保存其结构与记录。
无论是负责功能配置的顾问,还是动手写代码的开发者,理解 Odoo 的模型设计都是入门必备。模型不仅定义字段和表关系,还承载着业务逻辑和数据约束,是 Odoo 数据架构的基石。
那么系统如何记录这些模型本身的信息?答案是 ir.model。它相当于模型的目录或注册表,保存着系统中每个模型的元数据。无论是定制模块、调用 API 还是排查问题,都会频繁接触到 ir.model。
什么是 ir.model
ir.model 本质上是 Odoo 用来登记所有模型的元数据表。系统中每增加一个模型,都会在 ir.model 中产生一条记录;通过 Python 定义模型或用 Studio 创建模型,都会同步更新这一注册表。
这个模型属于核心 base 模块的一部分,参与框架级别的管理。无论是普通模型、抽象模型还是临时模型(transient),其元信息都会被纳入 ir.model 的管理范畴(注:抽象模型通常没有数据库表,不一定在注册表表现为普通条目)。
ir.model 与 ir.model.fields 密切相关:前者记录模型级别的信息,后者记录每个字段的元数据。两者配合实现对模型结构的反射和自省,使 Odoo 能动态发现与操作各种模型与字段。
开发者会在需要列出系统可用模型、检查继承关系或构建通用工具时查询 ir.model。通过 Odoo 的 XML-RPC / JSON-RPC 接口,也可以远程读取这些注册信息,便于集成与自动化。
模型中的核心字段
下面列出 ir.model 中比较重要的字段,帮你理解模型注册表包含哪些关键元信息,以便于排查和自动化脚本编写。
1. name
类型:Char。用于存放模型的可读描述文字,通常在技术设置和开发者工具中显示。该字段支持翻译,是用户在浏览模型列表时看到的标签。
2. model
类型:Char。模型的技术名称,用于代码中引用,例如 res.partner 或 sale.order。该字段为必填并建立索引以便快速检索。
3. info
类型:Text。用于记录关于该模型的补充说明或注释,便于文档化与内部沟通。多数模型可能为空,但在自定义或复杂模块中很有用。
4. state
类型:Selection。表示模型来源是系统基础模块(base)还是手工创建(如 Studio 或自定义代码)。基础模型通常受保护,手动创建的模型可更灵活地修改。
5. transient
类型:Boolean。为 True 时表示该模型为临时模型(wizard/临时数据)。这类模型的数据会被定期清理,不适合用于持久业务记录。
6. field_id
类型:One2many(ir.model.fields)。列出该模型上定义的所有字段。每条 ir.model.fields 记录描述一个字段的名称、类型及属性,便于字段级的自省。
7. access_ids
类型:One2many(ir.model.access)。定义该模型的访问控制规则,说明哪些用户组有创建、读取、修改或删除权限,是安全配置的重要来源。
8. rule_ids
类型:One2many(ir.rule)。记录规则(record rules),用于限制用户可见的记录范围,实现在行级别的访问控制。
9. inherited_model_ids
类型:Many2many(ir.model)。当模型通过继承扩展其他模型时,这里存放父模型的引用。查看该字段可以理解模型的继承链与功能来源。
10. modules
类型:Char。计算字段,列出定义或扩展该模型的模块名称。对于一个被多个模块扩展的模型,这里帮助追溯依赖关系。
11. sort
类型:Integer。用于在技术设置的模型列表中控制显示顺序,数值越小排位越靠前,便于整理大量模型。
12. constrains
类型:Text。存放 Python 层面的约束逻辑(@api.constrains 的代码片段),用于模型的自定义校验。
13. post_constrains
类型:Text。类似于 constrains,但用于后置校验场景,处理需要在事务后进行的验证逻辑。
14. sql_constraints
类型:Text。数据库层面的约束定义,例如唯一索引等,用于保证数据完整性并由数据库强制执行。
15. view_ids
类型:One2many(ir.ui.view)。计算字段,列出与该模型相关联的视图,有助于界面层的检查与管理。
16. record_count
类型:Integer。计算字段,显示该模型当前的记录数,便于评估数据量与做容量规划。
17. display_name
类型:Char。计算得出的显示名,通常结合 name 与 model 字段,用于在关联字段或下拉中友好展示。
18. create_date
类型:Datetime。记录条目创建时间,由 Odoo 自动维护,常用于审计与历史追踪。
19. create_uid
类型:Many2one(res.users)。创建该条记录的用户,用于审计与责任追踪。
20. write_date
类型:Datetime。最后一次修改时间,由系统自动更新,方便了解最近变更时间点。
21. write_uid
类型:Many2one(res.users)。上次修改该记录的用户,同样用于审计。
22. active
类型:Boolean。用于软删除或归档。当为 False 时表示该模型已停用或弃用,但数据仍保留在库中。
23. id
类型:Integer。数据库主键,用于在 API 或引用中唯一标识该 ir.model 记录。
24. restrict_functionality
类型:Boolean。指示在某些 Odoo 版本或许可下该模型功能是否受限,用于区分企业版与社区版的功能差异点。
25. is_mail_thread
类型:Boolean。指示该模型是否支持讨论(chatter)、消息与关注者机制,常见于需要协作与沟通的业务对象。
26. is_mail_activity
类型:Boolean。指示该模型是否支持活动(activity)模块,用于计划待办、跟进与下一步操作的追踪。
该模型在业务流程中的作用
1. 技术设置与配置查看
系统管理员通过技术设置浏览模型列表时,就是在查看 ir.model 的条目。界面会展示模型名称、说明和字段数量,便于定位需要调整的对象。
2. 权限与访问控制管理
在配置安全策略时,管理员通过 ir.model 的 access_ids 为不同用户组分配 CRUD 权限,从而控制系统中每类数据的可操作性。
3. Odoo Studio 的定制产物
用户在 Studio 中创建自定义模型时,系统会自动在 ir.model 中生成 state 为 manual 的记录,并同步创建相应的字段元数据,免去写代码的麻烦。
4. API 集成与发现层
外部系统在通过 XML-RPC/JSON-RPC 集成 Odoo 时,可先查询 ir.model 来发现可用模型与结构,避免在集成代码中硬编码不稳定的模型列表。
5. 模块开发与问题排查
开发者在开发或排查时会借助 ir.model 来理解继承关系(inherited_model_ids)和模型上的字段定义(field_id),以判定扩展是否正确或冲突所在。
开发者如何扩展该模型
开发者一般不会直接修改 ir.model 的底层方法。模型注册表由框架管理,通常只在定义或加载新模型时与之交互;若需定制行为,应该扩展那些被 ir.model 所描述的业务模型本身。
模型继承机制
在 Python 中使用 _inherit = 'res.partner' 之类的写法时,Odoo 会在注册表中反映出这种继承关系。新模型的 ir.model 条目会在 inherited_model_ids 中指向父模型,从而保持模型层次结构的同步与可追溯性。
新增字段的处理
当你给某个模型添加字段时,系统会创建相应的 ir.model.fields 记录并通过 model_id 关联到对应的 ir.model;而 ir.model 的模型级信息通常不需要变更。
Python 层扩展的常规做法
通常不会去重写 ir.model 自身的方法。如果需要改变系统行为,正确的做法是继承或扩展具体的业务模型(如 res.partner),而不是改动框架级的注册表。
通过 Odoo Studio 创建模型
使用 Studio 时,系统会替你建立 ir.model 与 ir.model.fields 的条目并处理 transient 标志。注意:抽象模型因为不创建实际数据库表,在注册表中的表现与普通模型不同。
最佳实践建议
- 在集成或编写自动化代码时,优先通过 ir.model 做自省与发现,而不是把模型名写死在代码里;这样能提高适配性并降低后续维护成本。
- 在查找模型元数据时,优先用 model 字段进行检索;它有索引并且是系统中唯一用于代码引用的技术名。
- 在编写扩展模块前,务必检查 inherited_model_ids 来理清继承链,避免重复定义字段或意外覆盖父模型逻辑。
- 通过 XML-RPC/JSON-RPC 等 API 安全地读取 ir.model 信息,而不是直接在数据库层面修改它;除非你在做类似 Studio 的平台工具,否则不推荐对注册表做手工改写。
- 当需要字段级别的元信息时,查阅 ir.model.fields,这能让你看到模型上每个字段的类型、参数与约束。
常见错误与坑点
- 不要直接修改 ir.model 的记录或手动篡改注册表。注册表由 Odoo 管理,手动改动可能导致系统不稳定或在升级时被覆盖。
- 不要混淆 ir.model(数据库中的注册记录)与 Python 类(模型定义)。二者相关但不同:一个是元数据记录,一个是运行时的类实现。
- 不要假设每个 Python 模型都有对应的 ir.model 条目。抽象模型通常没有独立数据库表,也不会像普通模型那样在注册表中留下完整记录。
- 注意临时模型的生命周期。transient 标志意味着其数据会被定期清理,切勿把持久业务数据放在临时模型中。
- 查询 ir.model 时务必加上筛选条件。生产环境中模型数量常常成百上千,宽泛查询会导致性能和可读性问题。
总结
ir.model 是 Odoo 中承载所有模型元信息的注册表。掌握它的关键字段和与 ir.model.fields 的关系,能帮助你更快地理解系统结构并定位问题。
无论你是通过技术设置查看系统、还是通过 API 集成外部系统,对 ir.model 有清晰的认知都能节省大量时间并避免常见错误。
需要我们协助您的 Odoo 实施吗?
Dasolo 专注于为企业提供 Odoo 实施、定制与性能优化服务。我们在 Odoo 数据架构与模型(包括 ir.model)方面有丰富的实战经验,擅长 API 集成与模块开发。
如需在 Odoo 上实现定制功能、开发模块或完成系统集成,我们可以提供专业支持与实施服务。 预约演示 与我们讨论您的项目需求。