Odoo13如何用check_access_rule校验删除权限控制按钮显隐
问题原因
原有代码存在4处错误,导致布尔字段值无法按预期生效:
- 权限API调用错误:
check_access_rule用于校验记录级访问规则,不适合判断模型级删除权限;且该方法是模型层面的方法,不能直接通过self.env.user(用户记录集)调用,perm_unlink是权限表字段名,不是合法的操作参数。 - 计算字段写法不符合Odoo规范:计算方法面向批量记录集执行,直接给
self.has_delete_access赋值无法适配多记录场景(如Tree视图逐行展示的需求),必须遍历记录集逐行赋值。 - 权限判断逻辑写反:需求为有权限时显示删除按钮,原有分支判断返回的布尔值和需求完全相反。
- 字段归属错误:代码中
has_delete_access定义在父模型上,但实际使用位置是some_ids关联的子模型Tree视图中,子模型行无法读取父模型的字段值。
正确实现
1. Python代码修正
如果some_ids是One2many关联的子模型,需要把权限计算字段定义在子模型上:
from odoo import models, fields # 子模型,对应some_ids的comodel_name class HrModelLine(models.Model): _name = 'hr.model.line' _description = 'Some Info Line' has_delete_access = fields.Boolean( compute="_compute_check_delete_access", string="Has Delete Access", default=False ) def _compute_check_delete_access(self): # 先校验模型级删除权限,不抛异常直接返回布尔值 has_model_unlink_perm = self.check_access_rights('unlink', raise_exception=False) for record in self: if not has_model_unlink_perm: record.has_delete_access = False continue # 再校验记录级删除规则,捕获无权限抛出的异常 try: record.check_access_rule('unlink') record.has_delete_access = True except Exception: record.has_delete_access = False
如果不需要校验记录级规则,只判断模型层面的删除权限,可以简化计算逻辑:
def _compute_check_delete_access(self): has_unlink_perm = self.check_access_rights('unlink', raise_exception=False) for record in self: record.has_delete_access = has_unlink_perm
2. XML视图修正
原有视图逻辑基本可用,注意把隐藏字段的属性从invisible改成column_invisible适配Tree视图行内隐藏,避免列占位:
<?xml version="1.0" encoding="UTF-8"?> <odoo> <record id="hr_some_id" model="ir.ui.view"> <field name="name">hr.model.form.inherit</field> <field name="model">hr.model_name</field> <field name="inherit_id" ref="hr_model_view_form_inherit"/> <field name="arch" type="xml"> <data> <xpath expr="//notebook/page[@name='page']/div[1]" position="before"> <group string="Some Info"> <field name="some_ids" readonly="True" nolabel="1"> <tree default_order="create_date desc"> <field name="has_delete_access" column_invisible="1"/> <button name="unlink" type="object" string="Delete" class="oe_stat_button" icon="fa-times" groups="base.group_user" attrs="{'invisible':[('has_delete_access','=',False)]}" /> </tree> </field> </group> </xpath> </data> </field> </record> </odoo>
关键API说明
check_access_rights(operation, raise_exception=True):校验当前用户对当前模型的操作权限,operation可选值为create/read/write/unlink,传入raise_exception=False时会直接返回布尔值,有权限返回True,无权限返回False。check_access_rule(operation):校验当前用户对记录集的记录级访问规则(即ir.rule中配置的域过滤权限),无权限时直接抛出AccessError,需要通过捕获异常判断权限结果。- 所有计算字段方法必须遍历
self记录集逐行赋值,禁止直接对self设置字段值,否则多记录场景下字段值不会正确更新。
内容的提问来源于stack exchange,提问作者Mirooo
相关产品推荐
相关产品推荐

