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
相关产品推荐
相关产品推荐

