2020-12-27 odoo权限管理原理之一

开源软件最详细的手册就是源代码,但源代码错综复杂,并不是最好的手册。关于odoo的权限管理,网上能找到的文章千篇一律,都不能把底层的实现原理讲清楚,只讲了四个级别的权限控制方法。我不满足于应用,对底层的实现原理也想搞清楚。研究了两天,终于梳理出了一些眉目,记录下来,并设计了一个案例,基本涵盖了权限控制的所有方面。经过深入研究,发现odoo的权限控制并不完美,有些需求仍需要重写底层代码才能实现,这也将在后面的案例中展示。
odoo权限管理原理系列将分三次介绍。今天介绍最基本的组类、组和用户的关系。后面将再写两个专题,依次介绍权限组如何控制菜单、视图、动作、模型、记录和字段,以及一个地产公司管理软件的权限设置案例。

1. 组类、组和用户

odoo权限控制的核心是用户组,菜单级、动作级、视图级、表级、记录级和字段级的权限控制都是围绕用户组展开。下图给出了与用户组密切相关的base模块中的4个基础模型ER关联图。


组类、组和用户.png

res_groups表中记录了odoo中定义的所有组,这些组使用外键category_id关联到ir_module_category表,实现组的分类管理,且这种分类可以形成树形结构。举个实际中的例子:有几个应用属于同一个公司开发的套件,这每一个应用都需要定义若干个权限组,而这些应用又可以进一步归属于这个开发公司。实现的效果如下所示,这是管理员打开的用户设置的界面,其中My Apps是我定义的一个根组类,其下还有两个子组类Fund和Estate。真正的权限组在Fund和Estate组类后的下拉列表里。


组类和组.png

对应的数据文件如下。数据文件可以以“security_模块名.xml”命名,放置在模块security目录下,并在__manifest__.py文件的data字段注册。
        <!-- 定义组类 -->
        <!-- 定义根组类My Apps -->
        <record model="ir.module.category" id="module_category_myapps">
            <field name="name">My Apps</field>
        </record>
        <!-- 定义子组类Estate和Fund,它们的parent_id字段通过XML ID指向My Apps -->
        <record model="ir.module.category" id="module_category_estate">
            <field name="name">Estate</field>
            <field name="parent_id" ref="module_category_myapps"/>
        </record>
        <record model="ir.module.category" id="module_category_fund">
            <field name="name">Fund</field>
            <field name="parent_id" ref="module_category_myapps"/>
        </record>

        <!-- 定义组,它们的category_id字段通过XML ID指向各自的组类 -->
        <!-- 为Estate应用定义两个权限组:Saler和Manager -->
        <record model='res.groups' id='group_saler'>
            <field name="name">Saler</field>
            <field name="category_id" ref="module_category_estate"/>
            <field name="implied_ids" eval="[(6,0,[ref('base.group_user')])]"/>
        </record>
        <record model='res.groups' id="group_manager">
            <field name="name">Manager</field>
            <field name="category_id" ref="module_category_estate"/>
            <field name="implied_ids" eval="[(6,0,[ref('base.group_user'),ref('group_saler')])]"/>
        </record>
        <!-- 为Fund应用定义两个权限组:Saler和Manager -->
        <record model='res.groups' id='group_fund_saler'>
            <field name="name">Saler</field>
            <field name="category_id" ref="module_category_fund"/>
            <field name="implied_ids" eval="[(6,0,[ref('base.group_user')])]"/>
        </record>
        <record model='res.groups' id="group_fund_manager">
            <field name="name">Manager</field>
            <field name="category_id" ref="module_category_fund"/>
            <field name="implied_ids" eval="[(6,0,[ref('base.group_user'),ref('group_fund_saler')])]"/>
        </record>

res_users表中保存了系统的所有用户,可以由管理员登录用户管理界面,为用户分配权限组。也可以通过数据文件向系统中导入用户和权限组,在导入用户和权限组的过程中就可以建立用户与权限组的关联关系。在base模块的res_users.py文件中,定义了res.users模型和res.groups模型,res.users模型中有一个groups_id字段对应了res.groups模型的users字段,它们都是many2many类型,在导入用户或者导入权限组时,可以通过eval="[(6,0,[ref('XML ID'),...])]"的方式建立用户和权限组的关联,它们的关联关系记录在res_groups_users_rel这张中间表中。
今天太晚了,明天接着梳理通过权限组控制菜单、视图、动作、模型、记录、字段。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容