07. 应用安全
在"模型和基础字段"章节中,我们创建了第一个用于存储业务数据的表。在 Odoo 这样的业务应用中,首先需要考虑的一个问题:哪些用户可以访问模块中的数据?Odoo 提供了一种安全机制,允许指定那些用户组可以访问模块数据。接下来将介绍一个新模块所需的最低安全访问配置,如何预设定用户组的访问规则(访问权限)。
1. 数据文件(CSV)
Odoo 是一个高度数据驱动的系统。操作和行为是通过 Python 代码进行定制的,但模块的价值部分在于加载时所设置的数据。加载数据的一种方式是通过 CSV 文件。一个例子是国家/地区列表,该列表数据在 base 模块安装时会被加载。
"id","country_id:id","name","code"
state_au_1,au,"Australian Capital Territory","ACT"
state_au_2,au,"New South Wales","NSW"
state_au_3,au,"Northern Territory","NT"
state_au_4,au,"Queensland","QLD"
...上面数据中的表头(第一行):
id是一个外部标识符。它可用于引用该记录(无需知道它在数据库中的标识符)。country_id:id通过其外部标识符来引用的国家/地区。name是国家/地区的名称。code是国家/地区的代码。
这三个字段在 res.country.state 模型中进行了定义。
按照惯例,导入数据的文件应位于模块的 data 文件夹中。如果数据与安全相关,则应位于 security 文件夹中;如果数据与视图和操作相关(稍后会介绍),则应位于 views 文件夹中。此外,所有这些文件都必须在__manifest__.py 文件中的 data 列表中进行声明。
另需注意,数据文件的内容仅在安装或更新模块时才会被加载。
数据文件将按照其在 __manifest__.py 文件中的顺序依次加载。也就是说,如果数据 A 引用了数据 B,则必须确保 B 在 A 之前加载。
以国家州为例,国家列表是在国家州份列表之前加载的。这是因为各州引用了相应的国家。
为何对安全性如此重要?因为模型的所有安全配置都是通过数据文件加载的,在下一节中将详细介绍。
2. 访问权限
默认情况下,Odoo 的每个模块需要预设定至少一个用户组的访问规则(访问权限)。如果未设定这个规则,则启动后会收到类似的警告信息:
WARNING odoodb odoo.modules.loading: The models ['estate.property'] have no access rules...如果模型上未定义任何访问权限,Odoo 会判定任何用户都无法访问该数据。系统甚至会在日志中进行提示:
WARNING odoodb odoo.modules.loading: The models ['estate.property'] have no access rules in module estate, consider adding some, like:
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink访问权限是使用模型 ir.model.access 中的记录来控制的。每个访问权限都与一个模型、一个组(如果是全局访问则不关联组)以及一组权限相关联:创建、读取、写入和解除链接。此类访问权限通常定义在一个名为 ir.model.access.csv 的 CSV 文件中。
实践一: 添加访问权限
继续上一节中创建的 property 模块的示例,新增一个文件:estate/security/ir.model.access.csv ,内容如下:
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_estate_property,access_estate_property,model_estate_property,base.group_user,1,1,1,1第一行中的字段说明如下:
id是一个外部标识符。name是ir.model.access的名称。model_id/id指代该访问权限所适用的模型。引用模型的标准方式是model_<model_name>,其中<model_name>是模型的名称,将其中的.替换为_。group_id/id指代该访问权限适用的组。perm_read,perm_write,perm_create,perm_unlink:读取、写入、创建和解除链接权限。
在相应的文件夹中创建 ir.model.access.csv 文件,并在__manifest__.py 文件中进行定义。为 base.group_user 组授予读取、写入、创建和删除链接的权限。
更新 estate/__manifest__.py 文件中的代码,如下:
{
'name': 'Estate',
'version': '1.0',
'depends': ['base'],
'author': 'winodoo',
'category': 'Services',
'description': """
一个学习 Odoo 开发的模块示例~
""",
'data': [
'security/ir.model.access.csv', # 新增内容
],
'demo': [
],
'installable': True,
'application': True,
'auto_install': False,
'icon': '/estate/static/images/icon.png',
'license': 'LGPL-3',
}运行系统加载并更新模块:
.\venv\Scripts\python.exe odoo-bin.py `
--db_host 127.0.0.1 --db_port=5432 -r userodoo `
-w 123456 -d odoodb --addons-path=addons -u estate `
--limit-time-real=120000或者使用 bat 脚本:
.\venv\Scripts\python.exe odoo-bin.py ^
--db_host 127.0.0.1 --db_port=5432 -r userodoo ^
-w 123456 -d odoodb --addons-path=addons -u estate ^
--limit-time-real=120000运行后控制台日志输出,如下图所示: 
相比之前,已经没有出现类似无权限规则的警告提示:
2026-05-01 21:39:03,543 17448 INFO doodb odoo.registry: module estate: creating or updating database tables
2026-05-01 21:39:04,003 17448 INFO doodb odoo.addons.base.models.ir_module: module estate: no translation for language zh_CN
2026-05-01 21:39:04,034 17448 WARNING doodb odoo.modules.loading: The models ['estate.property'] have no access rules in module estate, consider adding some, like:
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
estate.access_estate_property,access_estate_property,estate.model_estate_property,base.group_user,1,0,0,0