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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:25:23