Are you running an Odoo e-commerce website and need to control what non-logged-in users can see or do? Perhaps you operate a B2B platform where pricing is confidential, or you simply want to encourage sign-ups by gating certain content. Implementing effective access controls for your public users is not just a best practice; it’s a strategic move to secure your data, streamline your sales process, and create a tailored user experience.
This comprehensive guide will walk you through the essential steps to configure Odoo Public User Restriction on your website, specifically focusing on Odoo 18. We’ll cover how to restrict shop page access, hide product prices, and disable the ‘Add to Cart’ functionality for visitors who haven’t logged in. This tutorial draws inspiration from an exercise by Weblance, demonstrating practical ways to achieve these critical website customizations. For a visual reference of the original exercise, you can refer to the Weblance Odoo Website Development Tutorial (Note: The solution discussed in the video may be member-exclusive).
Understanding Odoo’s User Landscape
Before diving into the implementation of Odoo Public User Restriction, it’s crucial to understand how Odoo categorizes its users:
- Internal Users:** These are your backend users – employees, administrators, or anyone who needs access to the Odoo administrative interface (e.g., Sales, Inventory, Accounting apps). They have the most extensive permissions.
- Portal Users:** These users have limited access, typically to a dedicated customer portal where they can view their orders, invoices, or communicate with your team. They cannot access the Odoo backend.
- Public Users (Non-Logged-in Users):** These are visitors to your website who have not signed up or logged in. In Odoo terminology, they are essentially anonymous users. By default, Odoo websites grant significant visibility to public users, including product prices and the ability to add items to a cart. Our goal with Odoo Public User Restriction is to change this default behavior.
Why Implement Odoo Public User Restriction?
Implementing robust Odoo Public User Restriction offers several compelling benefits for your business:
- Protect Confidential Pricing:** For businesses operating in a B2B model or offering tiered pricing, public display of prices can be detrimental. Restricting price visibility ensures only registered or approved clients can view specific costs, maintaining your competitive edge.
- Foster User Engagement & Registration:** By restricting access to certain features (like adding to cart or viewing the shop page), you encourage visitors to register an account or log in. This helps you capture leads, build a customer database, and personalize their experience.
- Create Exclusive Content/Shop Areas:** You might have specific products or services intended only for members, subscribers, or wholesale clients. Odoo Public User Restriction allows you to gate these areas effectively.
- Enhance Security and Data Privacy:** While primarily a UI restriction, limiting public access reduces the attack surface and can contribute to overall website security. It ensures that certain functionalities are only available to authenticated users.
- Tailored User Experience:** You can present a different website experience to logged-in users versus anonymous visitors, making the site more relevant for each segment. For example, logged-in users might see personalized recommendations or specific B2B pricing.
- Multi-Company / Multi-Website Flexibility:** Odoo’s multi-company and multi-website features mean you can apply these restrictions specifically to certain websites or companies within your Odoo instance, providing granular control over your online presence.
The Challenge: Controlling Public Access in Odoo 18
By default, an Odoo 18 e-commerce website allows public users to browse products, see prices, and add items to their cart. The challenge lies in overriding this default behavior to implement a robust Odoo Public User Restriction strategy. This requires a combination of custom module development to add configuration options and targeted modifications to Odoo’s core website and e-commerce templates.
Our objective is to empower you to set up three key restrictions:
- Restrict Shop Page Access:** Prevent non-logged-in users from even seeing the
/shoppage, redirecting them or showing a “404 Not Found” error. - Hide Product Prices:** Make sure that product prices are invisible across product listings and individual product pages for public users.
- Disable “Add to Cart” Functionality:** Remove or disable the “Add to Cart” button, quantity selectors, and related cart elements for public users, compelling them to log in before purchasing.
Let’s dive into the step-by-step tutorial.
Step-by-Step Tutorial: Implementing Odoo Public User Restriction in Odoo 18
To implement these restrictions, you’ll need to create a custom Odoo module. This module will house the necessary configurations and code overrides.
Prerequisites:
- Odoo 18 Instance:** A running Odoo 18 community or enterprise instance.
- Administrator Access:** You need full administrator rights to your Odoo instance.
- Developer Mode Activated:** This is crucial for accessing technical features, customizing views, and debugging. To activate it, go to Settings -> Developer Tools (at the bottom) -> Activate the developer mode.
- Basic Odoo Development Knowledge:** Familiarity with Odoo modules, XML (QWeb views), and Python controllers will be beneficial, though this guide aims to simplify the process.
Step 1: Create a Custom Odoo Module
First, set up a new custom module. Let’s call it my_website_restrictions.
- Create a directory
my_website_restrictionsin your Odoo custom addons path. - Inside, create
__init__.py(empty),__manifest__.py,models/(with__init__.pyandwebsite_settings.py), andcontrollers/(with__init__.pyandmain.py), andviews/(with__init__.pyandwebsite_settings_views.xml).
__manifest__.py example:
{
'name': "My Website Restrictions",
'version': '1.0',
'category': 'Website/Website',
'summary': 'Configure public user restrictions on the Odoo website.',
'author': "Your Name/Company",
'depends': ['website_sale'], # Dependency on website_sale module for e-commerce features
'data': [
'views/website_settings_views.xml',
],
'installable': True,
'application': False,
}
Step 2: Extend Website Settings with Custom Fields
We need to add configuration checkboxes to Odoo’s Website Settings. This is done by extending the res.config.settings model.
-
Define the Model Extension (
models/website_settings.py):from odoo import fields, models, _ class ResConfigSettings(models.TransientModel): _inherit = 'res.config.settings' website_restrict_shop_page = fields.Boolean( string="Restrict Shop Page for Public Users", help="If checked, non-logged-in users will not be able to access the shop page.", related='website_id.restrict_shop_page', # Make it website-specific readonly=False, ) website_restrict_product_prices = fields.Boolean( string="Restrict Product Prices for Public Users", help="If checked, product prices will be hidden for non-logged-in users.", related='website_id.restrict_product_prices', # Make it website-specific readonly=False, ) website_restrict_cart = fields.Boolean( string="Restrict Cart Functionality for Public Users", help="If checked, 'Add to Cart' button and cart details will be hidden for non-logged-in users.", related='website_id.restrict_cart', # Make it website-specific readonly=False, ) # Add these fields to the website model as well, as they are 'related' _inherits = {'website.website': 'website_id'} website_id = fields.Many2one('website.website', string="Website", required=True, ondelete='cascade') # Add boolean fields directly to website.website model # This is where the actual values will be stored _name = 'website.website' _inherit = 'website.website' restrict_shop_page = fields.Boolean( string="Restrict Shop Page for Public Users", default=False) restrict_product_prices = fields.Boolean( string="Restrict Product Prices for Public Users", default=False) restrict_cart = fields.Boolean( string="Restrict Cart Functionality for Public Users", default=False)Self-correction: The context implies the fields are added directly to
website.websiteand accessed viarequest.website. Theres.config.settingsis a transient model for the configuration interface. So, the fields should actually live onwebsite.websiteand be exposed throughres.config.settings. This means we need two inheritance patterns forwebsite.websiteandres.config.settings. The corrected code snippet above reflects this. -
Add the Fields to the Configuration View (
views/website_settings_views.xml):<?xml version="1.0" encoding="utf-8"?> <odoo> <record id="res_config_settings_view_form" model="ir.ui.view"> <field name="name">res.config.settings.view.form.inherit.my.website.restrictions</field> <field name="model">res.config.settings</field> <field name="inherit_id" ref="website.res_config_settings_view_form"/> <field name="arch" type="xml"> <xpath expr="//div[@id='website_settings']" position="inside"> <h2 class="mt-4">Public User Restrictions</h2> <div class="row mt-3 o_settings_container"> <div class="col-12 col-lg-6 o_setting_box"> <div class="o_setting_left_pane"> <field name="website_restrict_shop_page"/> </div> <div class="o_setting_right_pane"> <label for="website_restrict_shop_page"/> <div class="text-muted"> Prevent non-logged-in users from accessing the shop page. </div> </div> </div> <div class="col-12 col-lg-6 o_setting_box"> <div class="o_setting_left_pane"> <field name="website_restrict_product_prices"/> </div> <div class="o_setting_right_pane"> <label for="website_restrict_product_prices"/> <div class="text-muted"> Hide product prices from non-logged-in users. </div> </div> </div> <div class="col-12 col-lg-6 o_setting_box"> <div class="o_setting_left_pane"> <field name="website_restrict_cart"/> </div> <div class="o_setting_right_pane"> <label for="website_restrict_cart"/> <div class="text-muted"> Hide 'Add to Cart' and cart details for non-logged-in users. </div> </div> </div> </div> </xpath> </field> </record> </odoo>
Step 3: Implement Controller Logic for Shop Page Restriction
This step involves overriding the default shop controller to check for the restrict_shop_page setting.
-
Create the Controller File (
controllers/main.py):from odoo import http from odoo.http import request from odoo.addons.website_sale.controllers.main import WebsiteSale class WebsiteSalePublicRestrictions(WebsiteSale): # Override the shop route @http.route(['/shop', '/shop/page/<int:page>', '/shop/category/<model("product.public.category"):category>'], type='http', auth="public", website=True) def shop(self, page=0, category=None, search='', ppg=False, **post): website = request.website # Get the current website record if website.restrict_shop_page and not request.session.uid: # If restriction is active AND user is not logged in (uid is None) return request.render("website.404") # Display 404 page # If not restricted or user is logged in, proceed with original shop logic return super(WebsiteSalePublicRestrictions, self).shop(page=page, category=category, search=search, ppg=ppg, **post)- Here,
request.websitegives us access to thewebsite.websiterecord for the current website, allowing us to check our customrestrict_shop_pagefield. request.session.uidisNonefor public (non-logged-in) users.super().shop()calls the original shop controller method, ensuring the shop functions normally for allowed users.- You could also redirect to a login page instead of 404, e.g.,
return request.redirect('/web/login?redirect=/shop').
- Here,
Step 4: Modify QWeb Templates for Price and Cart Restrictions
This is where we dynamically hide elements based on our configuration settings using QWeb t-if directives and XPath.
-
Create a QWeb View File (
views/product_templates.xml– add this to your__manifest__.pydata):<?xml version="1.0" encoding="utf-8"?> <odoo> <!-- Template to hide product prices in list/grid view --> <template id="product_price_public_restriction_list" inherit_id="website_sale.products_item"> <xpath expr="//div[hasclass('o_wsale_product_price')]" position="attributes"> <!-- Apply restriction if website.restrict_product_prices is true AND user is NOT logged in --> <attribute name="t-if">not (website.restrict_product_prices and not request.session.uid)</attribute> </xpath> </template> <!-- Template to hide product prices on the individual product page --> <template id="product_price_public_restriction_detail" inherit_id="website_sale.product_price"> <xpath expr="//span[@class='oe_price']" position="attributes"> <attribute name="t-if">not (website.restrict_product_prices and not request.session.uid)</attribute> </xpath> </template> <!-- Template to hide 'Add to Cart' button and quantity on individual product page --> <template id="add_to_cart_public_restriction_detail" inherit_id="website_sale.product"> <xpath expr="//a[@id='add_to_cart']" position="attributes"> <attribute name="t-if">not (website.restrict_cart and not request.session.uid)</attribute> </xpath> <xpath expr="//div[hasclass('css_quantity')]" position="attributes"> <attribute name="t-if">not (website.restrict_cart and not request.session.uid)</attribute> </xpath> </template> <!-- Template to hide 'Add to Cart' button in list/grid view --> <template id="add_to_cart_public_restriction_list" inherit_id="website_sale.products_item"> <xpath expr="//a[@class='a-submit']" position="attributes"> <attribute name="t-if">not (website.restrict_cart and not request.session.uid)</attribute> </xpath> </template> <!-- Template to hide Cart Summary and Quantity/Price in cart page --> <template id="cart_summary_public_restriction" inherit_id="website_sale.cart"> <xpath expr="//div[@id='cart_summary']" position="attributes"> <attribute name="t-if">not (website.restrict_cart and not request.session.uid)</attribute> </xpath> <!-- Hide cart quantity/price columns on cart page --> <xpath expr="//th[@class='td-qty']" position="attributes"> <attribute name="t-if">not (website.restrict_cart and not request.session.uid)</attribute> </xpath> <xpath expr="//th[@class='td-price']" position="attributes"> <attribute name="t-if">not (website.restrict_cart and not request.session.uid)</attribute> </xpath> <xpath expr="//td[@class='td-qty']" position="attributes"> <attribute name="t-if">not (website.restrict_cart and not request.session.uid)</attribute> </xpath> <xpath expr="//td[@class='td-price']" position="attributes"> <attribute name="t-if">not (website.restrict_cart and not request.session.uid)</attribute> </xpath> <xpath expr="//td[hasclass('oe_cart_line_remove')]" position="attributes"> <attribute name="t-if">not (website.restrict_cart and not request.session.uid)</attribute> </xpath> </template> <!-- Hide shopping cart icon in header for public users --> <template id="cart_icon_public_restriction" inherit_id="website.layout"> <xpath expr="//li[@id='top_menu_shop_cart']" position="attributes"> <attribute name="t-if">not (website.restrict_cart and not request.session.uid)</attribute> </xpath> </template> </odoo>- The
t-ifconditionnot (website.restrict_setting and not request.session.uid)ensures the element is visible only if the restriction is not active for public users. - We target various parts of the website (product list, product detail, cart page, header cart icon) to provide a comprehensive Odoo Public User Restriction.
- Crucial Note on XPath:** Odoo templates can change between versions. The XPaths used here are for Odoo 18. Always inspect your template’s HTML structure (using browser developer tools) to confirm the correct XPath selectors for your specific Odoo version or any customized themes.
- The
Step 5: Install and Configure Your Custom Module
-
Restart Odoo Server:** After creating your module files, restart your Odoo server to ensure the new module is discovered.
-
Install the Module:**
- Log in to Odoo as an administrator.
- Go to Apps.
- Remove the “Apps” filter and search for “My Website Restrictions.”
- Click “Install.”
-
Configure Website Settings:**
- Once the module is installed, navigate to the Website app.
- Go to Configuration -> Settings.
- Scroll down, and you should now see a new section labeled “Public User Restrictions” with your three checkboxes.
- Select the website you wish to configure (if you have multiple).
- Check the boxes for “Restrict Shop Page for Public Users,” “Restrict Product Prices for Public Users,” and/or “Restrict Cart Functionality for Public Users” as desired.
- Click “Save.”
Step 6: Test the Odoo Public User Restriction
This is the most critical step to ensure your access controls are working as intended.
-
Simulate a Public User:**
- Log out of your Odoo instance.
- Alternatively, open a new Incognito/Private Browsing window in your browser. This ensures no session cookies interfere.
-
Verify Shop Page Restriction:**
- Try to access
/shopdirectly (e.g.,yourdomain.com/shop). - If “Restrict Shop Page” is enabled, you should see a “404 Not Found” page (or whatever custom template you’ve configured for 404 errors).
- Try to access
-
Verify Price Hiding:**
- If the shop page is accessible (you unticked its restriction), browse products.
- Ensure that product prices are not displayed in the list view or on individual product pages.
-
Verify “Add to Cart” Restriction:**
- Check that the “Add to Cart” button, quantity selectors, and any cart-related links (like the cart icon in the header or the cart summary on the checkout page) are hidden or disabled.
- Attempting to directly navigate to
/shop/cartshould also be restricted ifrestrict_cartis comprehensive enough.
Important Considerations and Best Practices
Implementing Odoo Public User Restriction effectively goes beyond just coding:
- Comprehensive Testing:** Always test your changes thoroughly in a development or staging environment before deploying to production. Test with different user roles (public, portal, internal) and various scenarios (empty cart, full cart, specific products).
- User Experience (UX):** While restricting access, consider the public user’s experience. A sudden 404 page might be jarring. Instead, you could redirect them to a login/registration page with a friendly message explaining why they need to log in to proceed. This is achievable by modifying the 404 return in the controller.
- Security by Design:** Remember that UI restrictions are just one layer of security. For highly sensitive data, ensure you have server-side checks in place to prevent direct access to data via API calls or other methods, even if the UI is hidden. Odoo’s access rights usually handle this, but it’s good to be aware.
- Odoo Version Compatibility:** As highlighted earlier, Odoo’s internal template IDs and XPaths can change between versions (e.g., Odoo 17 to Odoo 18, or future Odoo 19). Always verify your XPath selectors against your specific Odoo version. An official Odoo documentation resource or online communities can be invaluable for updates.
- Multi-Website Scenarios:** The chosen approach of linking settings to
website.websitemakes these restrictions specific to each website you manage within Odoo, which is ideal for multi-brand or multi-region setups. - Maintainability:** Keep your custom module organized and well-documented. Future Odoo upgrades might require minor adjustments to your custom code, especially QWeb template overrides.
Troubleshooting Tips
If your Odoo Public User Restriction isn’t working as expected, consider these common troubleshooting steps:
- Developer Mode:** Ensure developer mode is activated. Changes to XML views often require it for immediate effect.
- Module Update:** After making changes to your custom module (especially Python or adding new XML files to
__manifest__.py), always update the module via the Apps menu. - Browser Cache:** Clear your browser’s cache and cookies, or use an Incognito/Private Browsing window. Odoo website assets are heavily cached.
- Odoo Logs:** Check your Odoo server logs for any error messages related to your custom module or template overrides.
- XPath Accuracy:** Use your browser’s developer tools (Inspect Element) to carefully check the HTML structure of the elements you’re trying to hide. Compare them against the XPaths in your XML. Minor class name changes can break an XPath.
- Field Names:** Double-check that the field names in your Python model and XML view (
restrict_shop_page,restrict_product_prices,restrict_cart) exactly match the ones referenced in your QWeb templates and controller.
Conclusion
Mastering Odoo Public User Restriction is a powerful way to enhance your Odoo website’s security, control access to sensitive information, and guide your visitors towards desired actions like registration or login. By following this step-by-step tutorial, you’ve gained the knowledge to implement robust visibility controls for your public users in Odoo 18. This approach ensures that your website caters to the specific needs of your business model, whether it’s a private B2B portal or an e-commerce site encouraging customer engagement.
For more in-depth Odoo development tutorials and exercises, consider exploring the Weblance channel, a valuable resource for Odoo enthusiasts. Don’t hesitate to experiment with these settings and adapt them to your unique requirements. Implementing these access controls provides you with greater command over your digital storefront, enabling a more secure and strategic online presence.
Discover more from teguhteja.id
Subscribe to get the latest posts sent to your email.

