Odoo15 为特定用户设置指定字段只读并保留管理员编辑权限
问题原因
- 核心逻辑错误:你对视图
groups_id属性的作用理解有误。Odoo中给ir.ui.view绑定groups_id的规则是:只有属于指定用户组的用户,才会加载该视图的修改内容。而Odoo系统管理员默认属于所有用户组,自然会加载你写的readonly规则,导致销售字段被锁无法编辑。 - 模型定义错误:你在
emd.sales模型中重复定义了两次date字段,Python类中同名字段会被后定义的内容覆盖,直接引发字段属性冲突。 - 视图定义错误:原表单视图中重复声明了两个
name="date"的字段,不符合Odoo视图规范,会导致字段渲染异常。 - 继承视图配置错误:你写的继承视图中
model指定为emd.accounts、inherit_id引用的是emd.emd_accounts_form_view,和你实际定义的emd.sales模型完全不匹配,会导致视图继承关系错乱。 - 字段修改写法冗余:你在修改
mode_of_sd字段属性时重复声明了widget="radio",属性注入时会覆盖原有属性,容易引发非预期的渲染问题。
正确实现方案
- 修复模型定义问题
删除财务字段区块中重复定义的date字段,保留销售区块的date定义即可,修正后的模型核心代码:
class emd_sales(models.Model): _name = 'emd.sales' _inherit = ['mail.thread', 'mail.activity.mixin'] _rec_name = 'tender_no' # 销售类字段 date = fields.Date(string='Date', tracking=True, default=fields.Date.context_today) company_id = fields.Many2one('emd.company', string='Company') customer_id = fields.Many2one('res.partner', string='Customer') product_id = fields.Many2one('product.template', string="Product", tracking=True) product_desc = fields.Char(string='Product Description') tender_no = fields.Char(string='Tender Number') tender_due_date = fields.Date(string='Tender Due Date', tracking=True) mode_of_sd = fields.Selection([('DD', 'DEMAND DRAFT'), ('BANK TRANSFER', 'BANK TRANSFER'), ('FDR', 'FDR'), ('ONLINE TRANSFER', 'ONLINE TRANSFER'), ('CREDIT CARD', 'CREDIT CARD')], required=True) amount = fields.Integer(string='Amount') # 财务类字段 bank_guarantee_no = fields.Integer(string='Bank Guarantee No.') instrument_no = fields.Integer(string='Instrument Number') bank_name = fields.Char(string='Bank Name') period = fields.Selection([ ('12 Months', '12 Months'), ('18 Months', '18 Months'), ('24 Months', '24 Months'), ('36 Months', '36 Months') ]) expiry_date = fields.Date(string='Expiry Date', tracking=True) remarks = fields.Text(string='Remarks')
- 修复表单视图权限逻辑
删除财务分组下重复的date字段,不需要新建绑定用户组的继承视图,直接在销售字段上写基于用户组的readonly判断即可精准控制权限,规则为:普通财务组用户(account.group_account_manager)查看销售字段时为只读,系统管理员(base.group_system)不受只读限制,可编辑所有字段。
修正后的表单视图核心代码:
<group> <group> <field name="date" readonly="user.has_group('account.group_account_manager') and not user.has_group('base.group_system')"/> <field name="company_id" readonly="user.has_group('account.group_account_manager') and not user.has_group('base.group_system')"/> <field name="customer_id" readonly="user.has_group('account.group_account_manager') and not user.has_group('base.group_system')"/> <field name="product_id" readonly="user.has_group('account.group_account_manager') and not user.has_group('base.group_system')"/> <field name="product_desc" readonly="user.has_group('account.group_account_manager') and not user.has_group('base.group_system')"/> <field name="tender_no" readonly="user.has_group('account.group_account_manager') and not user.has_group('base.group_system')"/> <field name="tender_due_date" readonly="user.has_group('account.group_account_manager') and not user.has_group('base.group_system')"/> <field name="mode_of_sd" widget="radio" readonly="user.has_group('account.group_account_manager') and not user.has_group('base.group_system')"/> <field name="amount" readonly="user.has_group('account.group_account_manager') and not user.has_group('base.group_system')"/> </group> <group> <field name="bank_guarantee_no" groups="account.group_account_manager"/> <field name="instrument_no" groups="account.group_account_manager"/> <field name="bank_name" groups="account.group_account_manager"/> <field name="period" groups="account.group_account_manager"/> <field name="expiry_date" groups="account.group_account_manager"/> <field name="remarks" groups="account.group_account_manager"/> </group> </group>
如果你坚持要用继承视图实现、不修改原视图,只需要删掉原继承视图中的groups_id字段,修正model和inherit_id的匹配错误,把每个字段的readonly属性值从硬编码的1替换为上述用户组判断表达式即可,不要给继承视图绑定任何用户组,否则管理员依然会被只读规则限制。
3. 可选后端权限兜底
如果需要做合规校验,防止用户通过接口绕过前端只读限制篡改销售字段,可以新增一条模型访问规则,给财务组用户授予销售类字段的读权限、收回写权限,和前端只读规则形成双重校验。
内容的提问来源于stack exchange,提问作者Dhiren Ahuja
相关产品推荐
相关产品推荐

