Odoo16配置:仅让选中字段可编辑的实现方法
Odoo16 实现指定字段可编辑(其余只读)方案
你之前的方案没生效,核心问题是用了computed many2many字段存储允许编辑的字段,但视图的attrs属性没法直接基于many2many记录集判断字段权限——attrs需要的是字段名的字符串列表,而非记录对象。下面是可行的实现步骤:
一、模型层调整
1. 确保配置模型的字段正确
假设你已经有一个用于配置的模型(比如自定义的custom.field.permission),里面的many2many字段用来关联允许编辑的字段:
from odoo import models, fields class CustomFieldPermission(models.Model): _name = 'custom.field.permission' _description = '字段编辑权限配置' model_id = fields.Many2one('ir.model', required=True, string='目标模型') editable_fields = fields.Many2many('ir.model.fields', string='允许编辑的字段', domain="[('model_id', '=', model_id)]")
如果是用res.config.settings做全局配置,记得处理对应字段的存储逻辑(通常用related或者自定义存储方法)。
2. 在目标模型添加计算字段(返回字段名列表)
在需要控制权限的业务模型里,新增一个计算字段,动态返回当前用户可编辑的字段名字符串列表:
from odoo import models, fields, api class TargetModel(models.Model): _inherit = 'your.target.model' # 替换成你实际的模型名 @api.depends_context('uid') def _compute_editable_field_names(self): # 这里根据你的配置逻辑获取对应权限记录,比如按当前模型匹配 permission_config = self.env['custom.field.permission'].search([ ('model_id.model', '=', self._name) ], limit=1) # 提取选中字段的名称,转成逗号拼接的字符串 self.editable_field_names = ','.join([field.name for field in permission_config.editable_fields]) editable_field_names = fields.Char(compute='_compute_editable_field_names', store=False)
这里用depends_context('uid')保证切换用户时重新计算权限,store=False表示不存储,动态计算即可。
二、视图层配置权限控制
在目标模型的表单视图中,给每个需要控制的字段添加attrs属性,判断当前字段名是否在允许列表里:
<record id="your_target_model_form_view" model="ir.ui.view"> <field name="name">your.target.model.form</field> <field name="model">your.target.model</field> <field name="inherit_id" ref="your_module.your_target_model_form_base"/> <field name="arch" type="xml"> <!-- 先把整个表单设为只读,确保默认所有字段不可编辑 --> <form position="attributes"> <attribute name="readonly">1</attribute> </form> <!-- 给需要放开编辑的字段单独设置权限 --> <field name="name" position="attributes"> <attribute name="attrs">{'readonly': [('editable_field_names', 'not like', 'name')]}</attribute> </field> <field name="email" position="attributes"> <attribute name="attrs">{'readonly': [('editable_field_names', 'not like', 'email')]}</attribute> </field> <!-- 其他需要控制的字段照此复制修改 --> </field> </record>
这里用not like是因为我们把字段名用逗号拼接成了字符串,只要包含目标字段名就表示允许编辑。
三、关键注意事项
- 字段名必须完全匹配:确保配置里选的
ir.model.fields的name值,和视图中用的字段名完全一致(比如关联字段是partner_id就不能写partner)。 - 权限逻辑可扩展:如果需要按用户/角色配置权限,只需要在
_compute_editable_field_names里加入对当前用户的判断即可(比如关联res.users或res.groups)。 - attrs优先级:字段级的
attrs会覆盖表单的全局readonly设置,所以能实现“整体只读,仅指定字段可编辑”的效果。
四、备选方案(基于用户组)
如果你的权限是按用户组划分的,也可以用Odoo自带的字段级权限(在模型设置里的“权限”标签配置),但如果需要管理员通过界面灵活配置任意字段,上面的方案更合适。
内容的提问来源于stack exchange,提问作者Manoj Yadav
相关产品推荐
相关产品推荐

