You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 23:03:31