*權限管理的四個層次
# 菜單級別:不屬於指定菜單所包含組的用戶看不到該菜單,不客全,只是隱藏
菜單,若知道菜單ID,仍然可以通過指定URL訪問
# 對象級別:對某個對角是否有'創建,讀取,修改,刪除'的權限,可以簡單理解為
表對象
# 記錄級別:對對象表中的數據的訪問權限,比如訪問“客戶”對象,業務員只能對自己創建
的客戶有訪問權限,而經理可以訪問其管轄的業務員所有的“客戶”對象
# 字段級別:一個對象或表上的某些字段的訪問權限,比如產品的成本字段只有經理有讀權限
'name':fields.char('Name',size=128,required=True,select=True,write=['base.group_admin']
read=['base.group_admin'])
定義name字段只能超級用戶組可讀寫
* 建立權限組
這是我們常說的用戶組,會通常放在“模塊名_security.xml”這個文件中
例如:
<record id="base.group_hr_manager" model="res.groups">
<field name="name">Manager</field>
<field name="comment">the user will have an access to the human resources configuration as well as statistic reports.</field>
<field name="category_id" ref="base.module_category_human_resources"/>
<field name="implied_ids" eval="[(4, ref('base.group_hr_user'))]"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>
@name:用戶組名,這個或以翻譯的
@comment:用戶組的注釋
@category_id 用戶組所屬的模塊名
@implied_ids 基於哪個用戶組,這個層級關系 <field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>是最基礎的
用戶名,最初是基於這個,后面一層一層遞增,像上面 base.group_hr_user 定義時就是基於最基礎
@users 預設用戶屬於這個用戶組
* 權限組
權限管理核心是權限組,每個權限組,可以設置權限組的 Menus,Access Right, Record Rule
# Menus:
定義該權限組可以訪問哪些菜單,若該權限組可以訪問某父菜單,父菜單對應的子菜單會顯示出來
若不想顯示其子菜單,可以把其子菜單加入 "Useablity/No One" 權限組。
# Access Right:
定義該權限組可以訪問哪些對象,以及擁有 增、查、改、刪的哪個權限 (create,read,write,unlink)
# Record Rule:
定義該權限組可以訪問對象中的哪些記錄,以及擁有 增、查、改、刪的哪個權限 ,Access Right是
對對象中的所有記錄賦權限,Record Rule 則通過定義domain過濾指定某些記錄賦權限
['&',('department','=',user.context_department_id.id),('state','=','pr_draft')]
申購單的部門等於當前用戶的部門,且申購單的狀態是草稿狀態
* 基於組的訪問控制
# 視圖中
運用group_id
<record id="view_order_form_editable_list" model="ir.ui.view">
<field name="name">sale.order.form.editable.list</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form" />
<field name="group_id" eval="[(6,0,[ref('product.group.uos'),
ref('product.group_stock_packaging'),
ref('sale.group_mrp_properties')])]" />
<field name="arch" type="xml">
<xpath expr="//field[@name='order_line]/tree" position="before"
<attribute name="editable" />
</xpath>
</field>
</record>
eval:把eval的值通過作為python運算返回該屬性
ref:視圖的方法,根據 module_name.xml_id 返回數據庫id
[(6,0,[xx,yy])]
(0,_ ,{’field’: value}) 這將創建一個新的記錄並連接它
(1,id,{’field’: value}): 這是更新一個已經連接了的記錄的值
(2,id,_) 這是刪除或取消連接某個已經連接了的記錄
(3,id,_) 這是取消連接但不刪除一個已經連接了的記錄
(4,id,_) 連接一個已經存在的記錄
(5,_,_) 取消連接但不刪除所有已經連接了的記錄
(6,_,[ids]) 用給出的列表替換掉已經連接了的記錄
這里的下划線一般是0或False
運用groups
<button name="invoice_pay_customer" type="object" string="Register Payment"
attrs="{'invisible': ['|', ('state','!=','open'), ('sent','=',True)]}" groups="base.group_user"/>
<field name="invoice_line_ids" groups="account.group_account_invoice"/>
<menuitem name="China Account" id="menu_china_account" parent="account.menu_finance" sequence="4" groups="account.group_account_user"/>
#在模型中
package_id = fields.Many2one(
comodel_name='stock.quant.package', string='Package',
related='quant.package_id', readonly=True,
groups="stock.group_tracking_lot")
要有多個用戶組時,用戶組之間用逗號隔開
#小結
只有在視圖中有完整標簽時,會用group_id,其它都用groups
*訪問權限管理:
對於其內的數據訪問權限管理有兩種機制:
第一種是模型訪問權限管理 (accessrule);
第二種是記錄規則管理 (record rule)。
record rule 是對accessrule的細化 ,帶條件,比如記錄是什么狀態的可以訪問
如果不為模塊設置規則,默認只有Administator才能訪問這個模型的數據
record rule 對 Administator 用戶是無效的,而access rule還是有效
# access rule
權限對象模型是 ir.model.access.csv
一般是放在security 文件夾下的 ir.model.access.csv 文件來管理的
文件表頭如下:
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
來一個例子:
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_payment_notice_account_user,payment.notice.account.user,model_payment_notice,account.group_account_user,1,1,1,1
access_payment_notice_sale_user,payment.notice.sale.user,model_payment_notice,base.group_sale_salesman,1,1,0,0
分析這個是針對 payment.notice 這個模型做訪問權限設置
可以看一下對應模型定義的代碼:
class PaymentNotice(models.Model):
_name = "payment.notice"
id:權限的ID不可重復 一般取名為 access_模型名_特定用戶組名(用下划線連起來)
name 描述 一般命名沿用模型名用“.”連接加 用戶組名
model_id:id:對象,命名是model_模型名(用下划線連起來)
group_id:id 組名稱 (模塊.用戶組名)
下面的,0 表示無權限, 1 表示有權限
perm_read 只讀
perm_write 修改
perm_create 創建
perm_unlink 刪除
# record rule
一般是放在security 文件夾下的 模塊名_record_rules.xml 文件來管理的
對於模型權限的補充
<?xml version=”1.0” encoding=”utf-8”?>
<openerp>
<data noupdate=”1”>
<record model="ir.rule" id="payment_notice_personal_rule">
<field name="name">Personal Payment Notice</field>
<field name="model_id" ref="model_payment_notice"/>
<field name="domain_force">['|',('claimed_user_id','=',user.id),('claimed_user_id','=',False)]</field>
<field name="groups" eval="[(4, ref('base.group_sale_salesman'))]"/>
</record>
<record model="ir.rule" id="payment_notice_see_all">
<field name="name">All Payment Notice</field>
<field name="model_id" ref="model_payment_notice"/>
<field name="domain_force">[(1,'=',1)]</field>
<field name="groups" eval="[(4, ref('account.group_account_user'))]"/>
<field name="perm_read" eval="1" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="1" />
</record>
</data>
</openerp>
record rule 記錄是 ir.rule 模型, 存在public.ir_rule 表格中
model_id 作用於哪個模型 值為 model_模型名
domain_force 對該模型中所有記錄進行某種過濾操作
常用的 ['|',('user_id','=',user.id),('user_id','=',False)] 表示是自己的單
user_id是記錄的字段,這個看實際情況改變, user.id 代表當前登錄用戶的id
[(1,'=',1)] 表示所有的單
noupdate 值為1 表示升級模塊不會更新本數據
base.group_user 是人力資源 / 雇員
perm_read 這些后面,是對 前面模型權限組設定的覆蓋
* 來一個完整的例子解說:
# 建立組
<record id="group_department_project_admin" model="res.groups">
<field name="name">A</field>
<fieldname="category_id" ref="B"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/> //把admin用戶加入該組中
</record>
@ name 組名稱
@ category_id 屬於哪個應用程序,或者哪個模塊,為了方便管理
@ users 組里面的用戶
這樣B應用程序就建立了一個名叫A的組。並且初始化了A組的一個用戶admin
# 組控制菜單顯示
A
<record model="ir.ui.menu" id=" memu_id1">
<field name="name" >menu1</field>
<field name="groups_id" eval="[(6,0,[ref('A'),ref('B')]),]"/>
<field name="sequence">1</field>
</record>
@ name 菜單名稱
@ groups_id 哪些組可以訪問該菜單
@ sequence 該菜單的序號
這樣A組與B組的成員都可以訪問menu1菜單,menu1菜單的顯示順序為1
注:eval 后面解釋,多個組訪問用“,”隔開
<menuitem id="menu_id2 " name="menu2" parent="menu_id1" sequence="1" groups="A,B "/>
@ name 菜單名稱
@ parent 父類菜單 如果沒有可以不寫parent
@ groups哪些組可以訪問該菜單
這樣menu1的子菜單menu2可以被A組合B組的成員訪問
# 權限規則
<record model="ir.rule" id="rule1">
<field name="name">rule1</field>
<field name="model_id" ref="model_model1"/>
<field name="global" eval="True"/>
<field name="domain_force">[1,’=’,1]</field>
<field name="groups" eval="[(4,ref('A'))]"/>
</record>
@ name 規則名稱
@ model_id 依賴的模塊
@ global 是否是全局
@ domain_force 過濾條件
@ groups 屬於哪個組
這樣A組的成員就可以取到model_model1的所有數據
# ir.model.access.csv
@id 隨便取
@name 隨便取
@model_id:id 這個就是你所定義的對象了
@group_id:哪個組
@perm_read","perm_write","perm_create","perm_unlink" 增刪改查權限了。1代表有權限
# Eval
many2many
(0,0,{values}) 根據values里面的信息新建一個記錄。
(1,ID,{values})更新id=ID的記錄(寫入values里面的數據)
(2,ID) 刪除id=ID的數據(調用unlink方法,刪除數據以及整個主從數據鏈接關系)
(3,ID) 切斷主從數據的鏈接關系但是不刪除這個數據
(4,ID) 為id=ID的數據添加主從鏈接關系。
(5) 刪除所有的從數據的鏈接關系就是向所有的從數據調用(3,ID)
(6,0,[IDs]) 用IDs里面的記錄替換原來的記錄(就是先執行(5)再執行循環IDs執行(4,ID))
例子[(6, 0, [8, 5, 6, 4])] 設置 many2many to ids [8, 5, 6, 4]
one2many
(0, 0,{ values })根據values里面的信息新建一個記錄。
(1,ID,{values}) 更新id=ID的記錄(對id=ID的執行write 寫入values里面的數據)
(2,ID) 刪除id=ID的數據(調用unlink方法,刪除數據以及整個主從數據鏈接關系)
例子:
[(0,0,{'field_name':field_value_record1,...}),(0,0,{'field_name':field_value_record})]
many2one的字段比較簡單,直接填入已經存在的數據的id或者填入False刪除原來的記錄。
# 隱藏的常用技巧
* 直接隱藏
<group name="owner" position="attributes">
<attribute name="invisible">True</attribute>
</group>
* 滿足某些條件的隱藏
<xpath expr="//field[@name='parent_id']" position='attributes'>
<attribute name="attrs">{'invisible': [('passenger','=', True)]}</attribute>
</xpath>
<group col="4" string='旅客信息' attrs="{'invisible': [('supplier','=', True)]}"></group>
* 通過組來隱藏
<xpath expr="//field[@name='type']" position="attributes">
<attribute name="groups">base.group_no_one</attribute>
</xpath>
* 菜單的隱藏
<record model="ir.ui.menu" id="crm.menu_crm_opportunities">
<field eval="[(6,0, [ref('base.group_no_one'),])]" name="groups_id"/>
</record>
* 代碼分析中的運用
#字段顯示權限
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
#在model中判斷
self.pool.get('res.users').has_group(cr, uid, 'sale.group_discount_per_so_line')
內容轉載 http://www.cnblogs.com/toby2chen/p/5177114.html