核心概念:外部标识符(External ID)
在 Odoo 中,model_id:id 和 group_id:id 字段的值,如 my_hostel.model_hostel_hostel 和 my_hostel.group_hostel_manager,并不是直接的数据库 ID,而是外部标识符。
-
外部标识符(External ID)是什么?
- 它是一个字符串,格式为
<module_name>.<unique_name>,例如my_hostel.model_hostel_hostel。 - 它在整个 Odoo 系统中唯一地标识一个数据库记录。
- 它通常用于在 XML 文件中引用数据库记录,例如在定义访问控制规则时。
- 它是一个字符串,格式为
-
为什么使用外部标识符?
- 避免硬编码 ID: 使用数据库 ID 最大的问题是,这些 ID 在不同的 Odoo 实例中可能不同。如果直接使用 ID,会导致代码无法跨实例移植。外部标识符则保证了跨实例的唯一性。
- 更易读: 外部标识符使用有意义的名称,而不是难以理解的数字 ID,提高代码可读性。
- 方便模块化: 使用外部标识符,模块之间的关联更加清晰,可以轻松地引用其他模块中的数据。
详细解释 model_id:id 和 group_id:id
-
model_id:id- 作用 : 此字段用于指定 访问规则 应用于哪个 模型 (数据库表)。
- 值 : 是一个外部标识符,例如
my_hostel.model_hostel_hostel。my_hostel: 模块名称。model_hostel_hostel: 在my_hostel模块中,定义hostel.hostel模型时的内部名称 (External ID)。注意,这里不是直接的模型名称hostel.hostel,而是一个在ir.model中表示hostel.hostel的记录的名称 (通常以model_开头)。
- 解析过程 :
- Odoo 根据点号 (
.) 分割外部标识符:my_hostel(模块名) 和model_hostel_hostel(模型记录名)。 - Odoo 在
ir.model表中查找module字段 等于my_hostel并且name字段 等于hostel.hostel(注意:这里是真实的模型名称) 的记录 (实际上,Odoo 内部会根据模块和模型名称生成一个ir.model记录)。 - 如果找到匹配的记录,Odoo 将获取该记录的
id字段 的值,并将其作为model_id:id的值,记录到访问控制规则中。
- Odoo 根据点号 (
-
group_id:id- 作用 : 此字段用于指定 访问规则 应用于哪个 用户组。
- 值 : 是一个外部标识符,例如
my_hostel.group_hostel_manager或my_hostel.group_hostel_user。my_hostel: 模块名称。group_hostel_manager或group_hostel_user: 在my_hostel模块中定义的用户组的内部名称 (External ID)。
- 解析过程 :
- Odoo 根据点号 (
.) 分割外部标识符:my_hostel(模块名) 和group_hostel_manager或group_hostel_user(用户组记录名)。 - Odoo 在
res.groups表中查找module字段 等于my_hostel并且name字段 等于hostel.manager(注意: 这里是用户组名称) 的记录 (实际上,Odoo 内部会根据模块和用户组名称生成一个res.groups记录)。 - 如果找到匹配的记录,Odoo 将获取该记录的
id字段 的值,并将其作为group_id:id的值,记录到访问控制规则中。
- Odoo 根据点号 (
举例说明
假设在你的 my_hostel 模块中,你定义了 hostel.hostel 模型,并且定义了 hostel.manager 和 hostel.user 这两个用户组。
-
ir.model表中的记录:Odoo 在你安装
my_hostel模块时会自动在ir.model表中创建一条记录,表示hostel.hostel模型:id module model name ... 10 my_hostelhostel.hostelmodel_hostel_hostel... 假设这条记录的
id是 10 。那么当 Odoo 解析my_hostel.model_hostel_hostel时,就会取id=10。 -
res.groups表中的记录:Odoo 在你安装
my_hostel模块时会自动在res.groups表中创建两条记录,表示hostel.manager和hostel.user这两个用户组:id module name ... 15 my_hostelhostel.manager... 16 my_hostelhostel.user...
假设这两条记录的 id 分别为 15 和 16。 那么当 Odoo 解析 my_hostel.group_hostel_manager 时,就会取 id=15; 解析 my_hostel.group_hostel_user 时,就会取 id=16。
-
访问规则:
在你的
ir.model.access.csv文件中,你可以有这样的规则:csvid,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_hostel_manager,hostel.manager.access,my_hostel.model_hostel_hostel,my_hostel.group_hostel_manager,1,1,1,1 access_hostel_user,hostel.user.access,my_hostel.model_hostel_hostel,my_hostel.group_hostel_user,1,0,0,0access_hostel_manager: 表示hostel.manager用户组对hostel.hostel模型有读、写、创建和删除的权限。access_hostel_user: 表示hostel.user用户组对hostel.hostel模型只有读的权限。
在数据库中, Odoo 会将规则记录为:
id model_id group_id perm_read perm_write perm_create perm_unlink ... 10 15 1 1 1 1 ... 10 16 1 0 0 0
总结
model_id:id和group_id:id使用外部标识符,而不是数据库 ID,以便跨 Odoo 实例保持一致性。- Odoo 会根据这些外部标识符在
ir.model和res.groups表中查找对应的记录,并获取其id值,从而实现对模型和用户组的引用。 - 这种方式使得访问控制规则更加灵活和可维护。