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

Odoo 15:如何让特定组用户隐藏指定菜单项?

Odoo反向权限控制:通过组隐藏指定菜单项的实现思路

你提到的需求是将用户加入特定组后隐藏指定菜单项,但Odoo的权限模型默认是「累加权限」——用户只要拥有任意一个菜单允许的组,就能看到该菜单,常规的groups_id配置无法直接实现反向隐藏。下面是几个可行的实现技巧:

方法一:重写菜单可见性计算方法(最直接)

Odoo菜单的可见性最终由ir.ui.menu的_visible_menu_ids方法决定,我们可以继承这个模型,在方法中加入判断逻辑:如果用户属于目标隐藏组,就从可见菜单列表中移除指定菜单项。

代码示例:

from odoo import models, api

class IrUiMenu(models.Model):
    _inherit = 'ir.ui.menu'

    @api.model
    def _visible_menu_ids(self):
        # 先调用原方法获取默认可见的菜单ID列表
        visible_menu_ids = super()._visible_menu_ids()
        
        # 判断当前用户是否在「Hide Contacts」组中
        hide_contacts_group = self.env.ref('your_module.group_hide_contacts')
        if hide_contacts_group in self.env.user.groups_id:
            # 获取要隐藏的菜单项ID
            contacts_menu_id = self.env.ref('contacts.menu_contacts').id
            # 如果该菜单在可见列表中,移除它
            if contacts_menu_id in visible_menu_ids:
                visible_menu_ids.remove(contacts_menu_id)
        
        return visible_menu_ids

优缺点:

  • 优点:逻辑直接,不影响其他权限,用户即使拥有其他能访问联系人的组,只要加入隐藏组就会被屏蔽
  • 缺点:需要编写Python代码,对自定义模块有依赖

方法二:利用组关联实现权限互斥

通过创建一个「允许访问联系人」的常规组,再让「Hide Contacts」组与它形成互斥关系——用户加入隐藏组时自动移除允许组的关联,退出时自动恢复。

代码示例(用户组自动同步):

from odoo import models, api

class ResUsers(models.Model):
    _inherit = 'res.users'

    @api.model
    def create(self, vals):
        user = super().create(vals)
        self._sync_hide_contacts_group(user)
        return user

    def write(self, vals):
        res = super().write(vals)
        if 'groups_id' in vals:
            for user in self:
                self._sync_hide_contacts_group(user)
        return res

    def _sync_hide_contacts_group(self, user):
        hide_group = self.env.ref('your_module.group_hide_contacts')
        show_group = self.env.ref('your_module.group_show_contacts')
        # 修改联系人菜单的groups_id为这个show_group
        if hide_group in user.groups_id:
            user.write({'groups_id': [(3, show_group.id)]})
        else:
            # 退出隐藏组时自动恢复访问权限
            if show_group not in user.groups_id:
                user.write({'groups_id': [(4, show_group.id)]})

优缺点:

  • 优点:利用Odoo原生权限模型,无需修改菜单可见性核心逻辑
  • 缺点:需要额外维护一个「允许访问」组,逻辑相对复杂

方法三:通过Action权限间接隐藏菜单

菜单的可见性依赖于其关联的Action权限,我们可以从Action层面控制,让加入隐藏组的用户无法访问对应Action,从而间接隐藏菜单。

代码示例:

from odoo import models, api

class IrActionsActWindow(models.Model):
    _inherit = 'ir.actions.act_window'

    @api.model
    def _get_action_domain(self):
        domain = super()._get_action_domain()
        if self.env.user.has_group('your_module.group_hide_contacts'):
            # 排除联系人对应的Action
            contacts_action_id = self.env.ref('contacts.action_contacts').id
            domain += [('id', '!=', contacts_action_id)]
        return domain

优缺点:

  • 优点:不仅隐藏菜单,还能限制用户通过其他入口(如快捷按钮)访问该功能
  • 缺点:会过度限制,可能影响其他依赖该Action的业务场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 23:09:53