Odoo开发中的权限管理
前言
本文开始前我们首先要知道的是,我们安装好odoo并配置好数据库之后,即便不加载任意一个模块,odoo也会在数据库中默认创建一些数据表。这些表就是用来存放模块的数据模型名、字段名、页面组件、权限配置等信息的,我们创建的每一个数据模型、模型的每一个字段、每一个模型的表单等等都是在odoo框架中都是以一条条数据记录的方式存储在数据库中的。
当我们为一个模型添加数据表单的时候,通常是先创建一个xml文件,而且文件中都是以固定的标签层级结构书写的,实际上所有的xml文件都在告诉我们,我们书写的配置并不是直接被框架渲染成对应的组件,都是在向数据库插入数据记录,然后odoo通过查看数据记录来完成对应的配置。
当然,向odoo的数据模型插入数据记录的方式有两种:
- 一种是创建xml文件,在每一条记录的record标签中通过model属性值来指定数据记录所对应的数据表。(菜单项menuitem标签实际上也是record标签加指定组件类型简化过来的,杠精先不要急着反驳我)
- 另一种就是通过创建与数据模型同名的csv文件,在文件中写入字段和数据记录,例如每个模块都有的security/ir.model.access.csv文件,这个文件就是向模型权限表插入数据用的
本文将以创建xml文件添加数据记录的方式向大家讲解odoo开发中用户权限组、模型权限、数据记录权限、数据字段权限分别是怎样实现的。
访问控制和权限管理的主要模型
在odoo中,控制数据访问和权限管理的主要是一下模型:
- ir.module.category:这是权限的分类,主要用来组织和管理安全组的,分类允许你将相关的安全组组织在一起,使得权限的管理和配置更加清晰和方便
- res.groups:这个模型用于定义安全组(Security Groups)。每个安全组可以包含多个用户,你可以为每个安全组分配不同的权限。安全组是权限管理的基础,你可以通过安全组来控制哪些用户可以访问哪些模型和记录。
- ir.model.access:这个模型用于定义模型级别的访问权限。每个ir.model.access记录都关联到一个模型和一个安全组,并定义了该安全组的成员可以对该模型执行哪些操作(创建、读取、更新、删除)。这是一种粗粒度的权限控制,用于控制用户可以访问哪些模型。
- ir.rule:这个模型用于定义记录级别的访问权限。每个ir.rule记录都关联到一个模型和一个或多个安全组,并定义了一个域(Domain),该域决定了该安全组的成员可以访问哪些记录。这是一种细粒度的权限控制,用于控制用户可以访问哪些具体的记录。
上述四个模型一起工作,就形成了odoo的权限管理系统,至于每个模型都有哪些字段,可以直接运行odoo激活开发者模型在设置->技术->数据库结构->模型中找到对应模型来查看。而在此之外想要实现同样的数据记录对不同的用户展示不同的数据字段,在odoo中就不属于权限管理的范畴了,但是可以通过创建多个列表视图区分用户做展示来实现。
创建分类和安全组
在你自己的模块目录下有一个security目录,我们把有关权限的所有xml文件都创建在这个目录下,后面不再赘述,最后还要记得把这些文件的路径添加的__manifest__.py文件的data变量下
<record id="module_category_my_category" model="ir.module.category">
<field name="name">My Category</field>
<field name="description">Description of my category</field>
</record>
<record id="group_manager" model="res.groups">
<field name="name">Manager</field>
<field name="category_id" ref="module_category_my_category"/>
</record>
<record id="group_user" model="res.groups">
<field name="name">User</field>
<field name="category_id" ref="module_category_my_category"/>
</record>
在这个示例中,我们创建了一个名为"My Category"的分类,并在该分类下创建了两个安全组:“Manager"和"User”。
创建安全组是用来定义不同的权限级别,分类是一种组织工具,用于使权限的管理和配置更加清晰和方便。它没有直接影响权限的行为,但可以使权限的结构更加合理和易于理解。
注:record标签中的id属性是我们认为定义的该记录的标识符,有时候我们在xml文件中向数据库表添加了数据记录,但模块尚未升级时数据记录是还没有插入到数据库表中的,另外数据库表中的id字段是自动分配的,有时候我们并不能在某个需要使用一条记录的时候直接写死一个id号。所以record标签中的id就有了意义,它可以作为数据库表id的平替,当我们需要引用某个数据记录时通过这个标识符就可以准确的指引到对应的记录
分配权限给安全组
通过ir.model.access记录来为特定模型分配CRUD(创建、读取、更新、删除)权限。
<record id="access_model_manager" model="ir.model.access">
<field name="name">model.access.manager</field>
<field name="model_id" ref="model_your_model"/>
<field name="group_id" ref="your_module.group_manager"/>
<field name="perm_read" eval="1"/>
<field name="perm_create" eval="1"/>
<field name="perm_write" eval="1"/>
<field name="perm_unlink" eval="1"/>
</record>
数据记录规则
记录规则允许你更精细地控制对记录的访问。可以通过ir.rule记录来定义这些规则。
<record id="rule_your_model_manager" model="ir.rule">
<field name="name">your_model.manager.rule</field>
<field name="model_id" ref="model_your_model"/>
<field name="groups" eval="[(4, ref('your_module.group_manager'))]"/>
<field name="domain_force">[('user_id', '=', user.id)]</field>
</record>
字段规则
在Odoo中,对于同一个数据模型的同一条数据,如果你希望不同的用户查看到的数据字段不一样,那么你可能需要使用视图和视图继承来实现。
Odoo的视图系统允许你为每个模型定义多个视图,每个视图可以显示模型的不同字段。然后,你可以使用记录规则和/或安全组来控制哪些用户可以访问哪些视图
以下是一个基本的步骤:
- 定义视图:首先,你需要为你的模型定义一个或多个视图。每个视图可以包含你希望显示的字段。
<record id="view_your_model_form" model="ir.ui.view"> <field name="name">your.model.form</field> <field name="model">your.model</field> <field name="arch" type="xml"> <form string="Your Model"> <field name="field1"/> <field name="field2"/> <!-- More fields here --> </form> </field> </record>
- 定义视图继承:然后,你可以定义一个或多个视图继承,以添加或删除字段。
在这个例子中,我们创建了一个新的视图,它继承自view_your_model_form视图,并且只对group_manager安全组的成员可见。这个视图删除了field2字段,并在field1字段后添加了field3字段<record id="view_your_model_form_manager" model="ir.ui.view"> <field name="name">your.model.form.manager</field> <field name="model">your.model</field> <field name="inherit_id" ref="your_module.view_your_model_form"/> <field name="groups_id" eval="[(4, ref('your_module.group_manager'))]"/> <field name="arch" type="xml"> <field name="field2" position="replace"/> <field name="field1" position="after"> <field name="field3"/> </field> </field> </record>