| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Lines of code | 118 |
| Technical Name |
hide_menus_per_user |
| License | LGPL-3 |
| Website | https://higa.group/ |
| Versions | 16.0 17.0 18.0 19.0 |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Lines of code | 118 |
| Technical Name |
hide_menus_per_user |
| License | LGPL-3 |
| Website | https://higa.group/ |
| Versions | 16.0 17.0 18.0 19.0 |
How it works
The module adds a Many2many field hidden_menu_ids on res.users pointing
to ir.ui.menu, restricted to root menus only. From there it does four things:
For each user, the module walks the menu tree under every selected root menu and collects the action models. Models also reachable from a non-blocked menu are excluded, so shared models (
res.partner, product.template...) keep working everywhere else. The result is
cached per user with ormcache.
_search is overridden so that, when the current user has at least one blocked model, queries
against those models return no records. The view still renders — the user just sees the standard
empty state.
List, kanban and form views inherit from
base with attributes that disable
create, edit, delete, duplicate,
import and export when the model is blocked for the user.
create() is overridden to raise AccessError on blocked models, so even an
external script using XML-RPC or JSON-RPC cannot bypass the restriction.
What is and is not protected
| Behavior | Status |
|---|---|
| Lists / kanban inside a blocked module | Empty |
| New / Edit / Delete / Duplicate buttons | Removed |
| Import (Upload) / Export buttons | Removed |
Direct create() via UI or RPC on a blocked model | Blocked (AccessError) |
| Reading a single record by URL | Still governed by standard Odoo security (groups + record rules) |
Framework models (ir.*, base.*, res.users, res.groups, res.company...) | Never blocked, even if listed under a blocked menu |
Key features
- Per-user configuration: set up directly on the user form, no security groups to create.
- Granularity by root menu: pick Sales, Purchase, Inventory, Invoicing... selecting a root applies to every exclusive sub-model.
- Smart scope: shared models (e.g.
res.partner,product.template) stay usable from non-blocked menus. - Framework-safe:
ir.*,base.*and coreres.*models are excluded from blocking on principle. - ORM-level enforcement: creation is blocked for direct API calls, not only in the UI.
- Cached and lightweight: blocked-model set is computed once per user and cached with
ormcache. - Reload, no logout: changes apply on the next page reload.
Installation
- Drop the module in your
addonspath (e.g./mnt/extra-addons/hide_menus_per_user). - Restart the Odoo server.
- Activate developer mode: Settings → Developer Tools → Activate the developer mode.
- Go to Apps, click Update Apps List, search for Hide Menus per User (the module is in the Tools category) and install.
Compatibility
| Odoo Version | Status | Notes |
|---|---|---|
| Odoo 16.0 | Supported | Views use <tree> tag. |
| Odoo 17.0 | Supported | Views use <tree> tag. |
| Odoo 18.0 | Supported | Views use <list> tag. |
| Odoo 19.0 | Supported | Views use <list> tag. |
FAQ
Why is the menu still visible? I expected it to be hidden.
By design. The user can still navigate to the module, but every list will be empty and there will be no buttons
to create, edit or export anything. If you also want the menu itself hidden, combine this module with security
groups.
Will the user still be able to read existing records by typing a record URL?
Reading a single record is still controlled by the standard Odoo security layer (groups and record rules). This
module focuses on listing, creating and editing. To fully forbid read, also remove the user from the relevant
security groups.
Does the change require a logout?
No, a page reload is enough.
Does it impact performance?
Negligible. The set of blocked models is cached per user with ormcache; the override only adds a
frozenset membership check on each _search call when the user has at least one blocked module
configured.
Can I block submenus only?
No. Restriction is by root menu and applies to every model exclusive to that subtree.
Does it work with multi-company?
Yes. The configuration is per user, so multi-company set-ups are supported transparently.
Enhance your team's security seamlessly.
Desarrollado por HIGA
Soluciones avanzadas para tu ecosistema Odoo.
Visita nuestra web para más información
License: LGPL-3
Please log in to comment on this module