In Odoo 18, controllers play a vital role in handling web requests, interacting with models, and rendering views to build dynamic web applications. By overriding existing controllers, developers can customize page behavior and extend Odoo’s core functionality according to their business needs.
To override an existing controller in Odoo 18, follow these steps:
1. Create a Controllers Directory
Inside your custom module, create a ‘controllers’ directory if it doesn’t already exist. Add an ‘__init__.py’ file inside this directory to import your custom controllers.
2. Import the Existing Controller
In your new controller file (e.g., custom_controller.py), import the existing controller from Odoo:
from odoo.addons.website_sale.controllers.main import WebsiteSale
from odoo.http import request
3. Create a Subclass and Override the Function
To modify an existing function, create a subclass that inherits from the original controller and overrides the desired method.
For example, let’s override ‘_prepare_product_values’, which is responsible for preparing product details before rendering the product page. We can modify it to add a custom message in the product description:
class CustomWebsiteSale(WebsiteSale):
def _prepare_product_values(self, product, category='', search='', **kwargs):
values = super()._prepare_product_values(product, category, search, **kwargs)
values['custom_message'] = "Limited Time Offer!"
return values
4. Override a Function with a Route
If the function you are overriding has a route, you must include the ‘@http.route’ decorator in your subclass.
Example: Modifying the ‘/shop’ Page to Change a Product Name
from odoo import http
from odoo.addons.website_sale.controllers.main import WebsiteSale
class WebsiteShop(WebsiteSale):
@http.route(['/shop', '/shop/page/<int:page>'], type='http', auth="public", website=True)
def shop(self, page=0, category=None, search='', min_price=0.0, max_price=0.0, ppg=False, **post):
res = super(WebsiteShop, self).shop(page, category, search, min_price, max_price, ppg, **post)
# Modify product name using qcontext
products = res.qcontext.get('products', [])
for product in products:
if product.id == 9:
product.name = 'Normal Desk'
return res
Override Function Using qcontext
When rendering a template, modifications can be applied using qcontext. This allows you to adjust existing parameters or introduce new values dynamically.
* Use qcontext to access or modify values before rendering.
* If additional values need to be passed or returned, update qcontext accordingly.
Handle Route Definition
When overriding a controller function with a route:
* Ensure that the inherited subclass includes the @http.route definition to avoid conflicts.
* Define the necessary modifications inside the subclass to extend or modify existing behavior.
Two Main Approaches to Override an Existing Function in Odoo 18
When overriding functions in Odoo, developers typically use one of the following two methods:
a) Function Overriding
In this method, the existing function from the parent class is copied into the inherited class, where it is modified as needed. This approach is useful when a complete overhaul of the function’s behavior is required.
b) Supering a Function
The super() method is used to inherit the existing functionality from the parent class while making minimal modifications. This approach preserves the core functionality and is useful for making small adjustments.
In summary, this article covers how to override existing controllers in Odoo 18 using different methods, such as leveraging qcontext for minor adjustments, modifying route-based functions, and completely overriding functions. By understanding and applying these techniques, you can efficiently customize and extend Odoo’s core functionality to better suit your business needs.
To read more about How to Override an Existing Controller in Odoo 17, refer to our blog How to Override an Existing Controller in Odoo 17.