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

Odoo按用户组条件禁用表单编辑按钮的正确实现方法

方案失效原因

你写的视图配置不生效有两个核心问题:

  • 给继承视图绑定groups_id仅控制该段视图修改是否对指定用户组生效,但根<form>标签的edit属性是全局视图属性,Odoo渲染时会合并所有同模型视图的配置,只要有其他视图未做相同限制,最终渲染结果就不会禁用编辑。另外你原代码中inherit_id的ref值没加模块前缀,也可能直接导致视图继承失败。
  • 这种静态写死edit="false"的方式是全局禁用该组对所有患者档案的编辑权,完全无法实现「仅不可编辑专家医生创建的档案、可编辑自己/同级别执业医生创建的档案」这类按记录维度判断的权限规则。
正确实现方案

需要同时做后端权限兜底和前端体验优化,两层配合才能既满足安全要求,又符合操作体验:

1. 配置后端记录规则(必做,安全兜底)

所有前端限制都可以被技术手段绕过,必须通过Odoo原生的记录规则(ir.rule)做行级权限控制,直接新增如下XML配置即可:

<record id="rule_patient_pratisyen_no_edit_expert" model="ir.rule">
    <field name="name">执业医生不可编辑专家创建的患者档案</field>
    <field name="model_id" ref="om_hospital.model_hospital_patient"/>
    <field name="domain_force">[
        ('create_uid.groups_id', 'not in', [ref('om_hospital.hospital_management_expert_doctor')])
    ]</field>
    <field name="groups" eval="[(4, ref('om_hospital.hospital_management_pratisyen_doctor'))]"/>
    <field name="perm_read" eval="True"/>
    <field name="perm_write" eval="False"/>
    <field name="perm_create" eval="True"/>
    <field name="perm_unlink" eval="False"/>
</record>

规则逻辑:仅对执业医生组生效,开放所有患者档案的查看、新建权限,但仅当档案创建者不属于专家医生组时,才开放编辑、删除权限。规则生效后,执业医生就算绕过前端直接调用接口修改专家创建的档案,也会被后端直接拦截。

2. 前端表单动态控制(优化操作体验)

后端规则生效后,用户点击编辑再保存才会弹出权限报错,体验较差,可以通过动态表单属性实现符合条件的记录自动只读:

第一步:给患者模型新增计算字段,判断当前记录的编辑权限

from odoo import models, fields, api

class HospitalPatient(models.Model):
    _inherit = 'hospital.patient'

    can_edit = fields.Boolean(compute='_compute_can_edit', default=True)

    def _compute_can_edit(self):
        is_pratisyen = self.env.user.has_group('om_hospital.hospital_management_pratisyen_doctor')
        expert_group = self.env.ref('om_hospital.hospital_management_expert_doctor')
        for record in self:
            # 非执业医生组用户默认有全部编辑权
            if not is_pratisyen:
                record.can_edit = True
                continue
            # 执业医生仅可编辑非专家创建的档案
            record.can_edit = expert_group not in record.create_uid.groups_id

第二步:修改表单视图,绑定动态编辑属性

<record id="view_patient_form_edit_control" model="ir.ui.view">
    <field name="name">hospital.patient.form.edit.control</field>
    <field name="model">hospital.patient</field>
    <field name="inherit_id" ref="om_hospital.view_patient_form"/>
    <field name="arch" type="xml">
        <xpath expr='//form' position='attributes'>
            <attribute name="edit">can_edit</attribute>
        </xpath>
    </field>
</record>

配置生效后,用户打开患者档案时,表单会自动根据当前记录的can_edit值判断是否允许进入编辑模式:执业医生打开自己或其他执业医生创建的档案时可正常编辑,打开专家创建的档案时表单直接为只读状态,无需给每个字段单独加readonly属性,后续新增字段也不需要额外调整权限配置。

其他方案说明

不推荐通过attrs给所有字段逐个加只读属性的方案,这种方式维护成本极高,后续模型新增字段时很容易遗漏权限配置,留下安全漏洞。

内容的提问来源于stack exchange,提问作者Enes Kara

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:01:07