设置-用户中编辑用户信息是我们常用到的功能,但是当我们在开发者权限下查看用户form视图字段时,里面访问权限字段设置却显示如下:
这确实很让人困惑.
在Ruter的这篇权限组的设置中介绍了权限组的实现.
从这篇文章的实现中我们可以很直观了解到在xml中设置model="ir.module.category"
的record,用户视图中权限字段的显示会多出一个新分类,在分类下可以选择他们的子项(也就是model="res.groups"
的record),当选择完时,可以发现用户被加入到了相关权限组中.
看到这里,也许你已经大概猜到了我接下来要说什么了.
在addons/base/res/res_users_view.xml
中我们可以发现id="view_users_form"
的record,是用户表单视图的基本实现,通过对比源码以及odoo开发者模式下的字段视图获取,他们之间的主要差别是源码中的
被替换成了开头所说的让人费解的字段.
在继续从源码中查找,我们还可以发现另外一段在同文件下继承了id="view_users_form"
的一个id="user_groups_view"
的record.在这段record中,主要定义了
也就是说groups_id
的字段的显示部分已经id="user_groups_view"
被替换了.
从开发者模式下进入设置-页面-视图 中搜索这个id,可以发现这个视图的结构完全与被替换掉
的用户视图一致.
但是,在XML中,id = user_groups_view
的record中并没有定义出具体字段,那么odoo是如何精确的把相关分组设置加入到用户的视图呢?
在addons/base/res/res_users.py
中发现了一个继承了res.groups
的类GroupsView
里面存在一个方法_update_user_groups_view
,在这个方法的介绍里,作者介绍了作用:
Modify the view with xmlid
base.user_groups_view
, which inherits
the user form view, and introduces the reified group fields.
这段代码即便没仔细的阅读,我们也可以很轻松的了解到大体功能:得到所有application(也就是categroy),
构造出field,其中field会根据该选项是否是selection
类型以及其他处理(意味着选项是boolean
)
最后,把构造好的XML重新写入数据库中id = user_groups_view
的记录.
再仔细阅读,可以发现方法中循环的主题是通过for app, kind, gs in self.get_groups_by_application():
这段代码生产的.这段代码作者也给出了相关介绍:
Return all groups classified by application (module category), as a list::
[(app, kind, groups), ...],
whereapp
andgroups
are recordsets, andkind
is either'boolean'
or'selection'
. Applications are given in sequence
order. Ifkind
is'selection'
,groups
are given in
reverse implication order.
至于看起来很奇怪的字段名,在源码中有一段name_selection_groups
的方法:
def name_selection_groups(ids):
return 'sel_groups_' + '_'.join(map(str, ids))
可以发现_update_user_groups_view
中在对字段处理的时候调用了该方法,所以field字段显示的逻辑是各种不同权限中包含的的groups_id的组合.(对应implied_ids
字段,分组包含其他分组的权限)
_update_user_groups_view
方法会在页面升级的时候调用一次生成视图,此外,每当res.groups
模型中执行了创建,删除,修改操作也会同时执行该段函数更新视图
知道了原理,操作这部分就变得十分轻而易举了.首先继承res.groups模块,然后重写_update_user_groups_view
方法
@api.model
def _update_user_groups_view(self):
super(SpeGroupsView, self)._update_user_groups_view()
# 修改base.user_groups_view视图,把Admin设置只分配给超级管理员
view = self.env.ref('base.user_groups_view', raise_if_not_found=False)
etree = ET.fromstring(view.arch)
change_field = etree.find(".//field[@name='sel_groups_1_2']")
if change_field is not None:
change_field.set('groups', 'base.group_system')
xml_content = ET.tostring(etree, encoding='utf-8', method='xml')
view.with_context(lang=None).write({'arch': xml_content})
这段代码中等odoo的原本的处理完毕之后,我们再取出来,根据自己的需要操作XML(就跟平时编写xml一样),
在这里,我对 系统管理
字段设置了groups,只有group_system
权限组才可以看的到该视图.
然后重新与原方法一样,重新写回数据库中.
作者:findsomeoneys
链接:https://www.jianshu.com/p/7fd0dbacc5c5
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。