ODOO权限管理

  • Post author:
  • Post category:其他


权限等级


  • 第一级是


    access rule


    ,即表级(对象)权限,控制用户组对某个对象是否有创建、读取、修改、删除的权限,一般是用


    security/ir.model.access.csv


    文件来管理。

  • 第二级是


    行级权限,控制用户组对表中数据行的访问权限,可以写在


    views/views.xml


    文件中。
  • 第三级是字段级权限,一个对象或表上的某些字段的访问权限。
  • 第四级是菜单级

    权限

    ,不属于指定菜单所包含组的用户看不到该菜单。

其实简单的理解就是

对于数据表Table A


用户能不能看见这个表的内容(字段及数据),就是表级权限

用户能不能看见表A的某行(数据),就是行级权限(记录及权限)

用户是否能看见表A的字段(列),就是字段及权限

对于odoo的菜单,用户是否可见,就是菜单级权限

创建模块

版本:odoo8


(python 2.7


环境


)

python ./odoo.py scaffold academy ./openerp/addons_test

切换用户到开发者模式

右上角用户,点击关于,页面右上角“激活开发者模式”

更新模块列表

Settings->Modules->Update Modules List

安装模块


Settings->


右上角搜索模块名

一、表级权限

新建model

academy/models.py

class Teachers(models.Model):
    _name = 'academy.teachers'

    name = fields.Char('Teacher Name')
    biography = fields.Html()
    user_id = fields.Many2one('res.users', string="User", ondelete='cascade', required="true")

class Courses(models.Model):
    _name = 'academy.courses'
    name = fields.Char()
    teacher_id = fields.Many2one('academy.teachers', string="Teacher")
    course_ids = fields.One2many('academy.courses', 'teacher_id', string="Courses")

给两个表添加基本的视图以及新建两个菜单

academy/views.xml

<openerp>
    <data>
        <record id="action_academy_teachers" model="ir.actions.act_window">
            <field name="name">Academy teachers</field>
            <field name="res_model">academy.teachers</field>
        </record>

        <record id="academy_teacher_tree" model="ir.ui.view">
            <field name="name">Academy teachers: tree</field>
            <field name="model">academy.teachers</field>
            <field name="arch" type="xml">
                <tree>
                    <field name="user_id"/>
                </tree>
            </field>
        </record>
        <record id="academy_teacher_form" model="ir.ui.view">
            <field name="name">Academy teachers: form</field>
            <field name="model">academy.teachers</field>
            <field name="arch" type="xml">
                <form>
                    <sheet>
                        <label for="user_id"/> <field name="user_id"/>
                        <label for="biography"/>
                        <field name="biography"/>
                    </sheet>
                </form>
            </field>
        </record>

        <record id="action_academy_courses" model="ir.actions.act_window">
            <field name="name">Academy courses</field>
            <field name="res_model">academy.courses</field>
        </record>
        <record id="academy_course_search" model="ir.ui.view">
            <field name="name">Academy courses: search</field>
            <field name="model">academy.courses</field>
            <field name="arch" type="xml">
                <search>
                    <field name="name"/>
                    <field name="teacher_id"/>
                </search>
            </field>
        </record>
        <record id="academy_course_list" model="ir.ui.view">
            <field name="name">Academy courses: list</field>
            <field name="model">academy.courses</field>
            <field name="arch" type="xml">
                <tree string="Courses">
                    <field name="name"/>
                    <field name="teacher_id"/>
                </tree>
            </field>
        </record>
        <record id="academy_course_form" model="ir.ui.view">
            <field name="name">Academy courses: form</field>
            <field name="model">academy.courses</field>
            <field name="arch" type="xml">
                <form>
                    <sheet>
                        <label for="name"/>
                        <field name="name"/>
                        <label for="teacher_id"/>
                        <field name="teacher_id"/>
                    </sheet>
                    <div class="oe_chatter">
                        <field name="message_follower_ids" widget="mail_followers"/>
                        <field name="message_ids" widget="mail_thread"/>
                    </div>

                </form>
            </field>
        </record>

        <menuitem sequence="0" id="menu_academy" name="Academy"/>
        <menuitem id="menu_academy_content"
                  parent="menu_academy"
                  name="Academy Content"/>
        <menuitem id="menu_academy_content_teachers"
                  parent="menu_academy_content"
                  action="action_academy_teachers"/>
        <menuitem id="menu_academy_content_courses"
                  parent="menu_academy_content"
                  action="action_academy_courses"/>
    </data>
</openerp>

表级的权限控制文件在academy/security/ir.model.access.csv

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_academy_teachers,access_academy_teachers,model_academy_teachers,,1,0,0,0

如上的group_id没有加,就是对所有组公开了teacher表的读取权限,重启odoo并升级(admin),切换用户(非admin),可看到效果页面:


可以看到该用户对teacher仅有读取权,但添加、修改、删除不能操作。

二、行级权限

比如访问“客户”对象,业务员只能对自己创建的客户有访问权限,而经理可以访问其管辖的业务员所有的“客户”对象。在ir.rule模型中定义规则,存储在public.ir_rule表格里面。

新建规则文件security/academy_record_rules.xml,并注册到__openerp__.py的data的属性中。

security/academy_record_rules.xml

<?xml version="1.0" encoding="utf-8"?>
<openerp>
    <data noupdate="1">
        <record id="academy_user_rule" model="ir.rule">
            <field name="name">Academy only for owner</field>
            <field name="model_id" ref="model_academy_teachers"/>
            <field name="domain_force">
                [('create_uid','=',user.id)]
            </field>
            <!--<field name="groups" eval="[(4,ref('base.group_user'))]"/>-->
        </record>
    </data>
</openerp>

name 规则名称

model_id 对应的模型

global 是否是全局

domain_force 过滤条件,在创建id等于当前用户id时,显示该条记录

groups 属于哪个组

base.group_user



是所有组,可以不写



security/ir.model.access.csv


id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_academy_teachers,access_academy_teachers,model_academy_teachers,,1,1,1,1
access_academy_courses,access_academy_courses,model_academy_courses,,1,0,0,0

先开放teacher模块对所有组的所有权限,重启Odoo并升级academy,登陆非admin用户,可以看到teacher可新建,并只能看见自己创建的数据。

注释

(4,ID)添加主从链接关系到id=ID的对象。

(3,ID)去除和id=ID的对象主从链接关系,但是不删除这个对象

(2,ID) 去除和id=ID的对象主从链接关系,并且删除这个对象(调用unlink方法)

(5) 去除所有的链接关系,也就是循环所有的从数据且调用(3,ID)

(6,0,[IDs]) 用IDs里面的记录替换原来链接的记录,即先执行(5)再循环IDs执行(4,ID)

三、字段级权限

创建用户的权限组使用record记录,存储在res.groups里

security/academy_groups.xml

<?xml version="1.0" encoding="utf-8"?>
<openerp>
    <data noupdate="1">
        <record model="ir.module.category" id="module_category_academy_test">
            <field name="name">academy test</field>
        </record>
        <record id="academy_teachers_group" model="res.groups">
            <field name="name">Academy teachers group</field>
            <field name="comment">the comment of the group.</field>
            <field name="category_id" ref="module_category_academy_test"/>
            <!--<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>-->
            <!--<field name="users" eval="[(4, ref('base.user_root'))]"/>-->
        </record>
        <record id="academy_managers_group" model="res.groups">
            <field name="name">Academy managers group</field>
            <field name="comment">the comment of the group.</field>
            <field name="category_id" ref="module_category_academy_test"/>
        </record>
    </data>
</openerp>

首先定义了分组category,然后定义了两个组属于同一分组(也可以不写分组)。

注释

name 组名

comment 组的注释

category_id 所属于哪个模块

users 预定义属于该组的用户

implied_ids

在demo.xml中添加两条记录,创建两个用户

demo.xml

        <record id="user_teacher_a" model="res.users">
            <field name="name">teacherA</field>
            <field name="login">teacher.a@email.com</field>
            <field name="password">academy</field>
        </record>
        <record id="user_teacher_b" model="res.users">
            <field name="name">teacherB</field>
            <field name="login">teacher.b@email.com</field>
            <field name="password">academy</field>
        </record>

        <record id="teacher_a" model="academy.teachers">
            <field name="name">TeacherA</field>
            <field name="work_email">teacher.a@academy.com</field>
            <field name="user_id" ref="academy.user_teacher_a"/>
        </record>
        <record id="teacher_b" model="academy.teachers">
            <field name="name">TeacherB</field>
            <field name="work_email">teacher.b@academy.com</field>
            <field name="user_id" ref="academy.user_teacher_b"/>
        </record>

登陆admin给teacherA添加到academy_teachers_group组,设置->用户 找到teacherA编辑,会看到权限多了分组,勾选Academy teachers group。


给字段添加组权限有两个地方

在视图中给field加groups属性

academy/views.xml

        <record id="academy_teacher_tree" model="ir.ui.view">
            <field name="name">Academy teachers: tree</field>
            <field name="model">academy.teachers</field>
            <field name="arch" type="xml">
                <tree>
                    <field name="user_id"/>
                    <field name="name"/>
                    <field name="biography" groups="academy.academy_teachers_group"/>
                    <field name="show_group_teacher"/>
                </tree>
            </field>
        </record>

或者在字段定义的地方加groups属性

academy/models.py

class Teachers(models.Model):
    _name = 'academy.teachers'

    name = fields.Char('Teacher Name')
    biography = fields.Html()
    user_id = fields.Many2one('res.users', string="User", ondelete='cascade', required="true")
    show_group_teacher = fields.Char('Show For Teacher', groups="academy.academy_teachers_group")

重启odoo并升级academy,可以登陆TeacherA和TeacherB查看效果。

四、菜单级权限

在菜单定义处加groups属性(或者groups_id)

academy/views.xml

        <menuitem id="menu_academy_content_courses"
                  parent="menu_academy_content"
                  action="action_academy_courses"
                  groups="academy.academy_teachers_group"/>

重启odoo并升级academy,可以登陆TeacherA和TeacherB查看效果。



版权声明:本文为Heathy__原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。