Enable Dark Mode!
how-to-override-an-existing-controller-in-odoo-19.jpg
By: Saneen K

How to Override an Existing Controller in Odoo 19

Technical Odoo 19 Odoo Enterprises Odoo Community

In the Odoo 19 framework, controllers serve as the critical bridge between the web browser and the server's business logic. They process incoming HTTP requests, orchestrate interactions with Odoo models, and ultimately dictate the response, whether it's a rendered webpage, JSON data, or a file download. A common and powerful customization technique involves overriding existing controllers to modify default behavior, inject new data, or completely alter response logic without changing the core codebase.

This guide outlines the systematic process for extending and overriding controllers in Odoo 19.

Establishing the Module Structure

The first step is to ensure your custom module is properly structured to hold controller files.

  • Create a /controllers directory at the root of your module.
  • Inside this directory, create an __init__.py file. This file must import any other Python files you create within the controllers folder.
  • Create your controller file (e.g., custom_controllers.py).

Your module structure should look like this:

my_custom_module/
+-- controllers/
¦   +-- __init__.py
¦   +-- custom_controllers.py
+-- __init__.py
+-- __manifest__.py
+-- ... (other files)

The __init__.py inside the controllers directory should contain:

from . import custom_controllers

And the main __init__.py file should import the controllers directory:

from . import controllers

Importing the Base Controller

Within your new controller file, you must import the original controller you intend to extend. This is typically found within the controllers directory of another Odoo addon.

from odoo import http
from odoo.addons.website_sale.controllers.main import WebsiteSale

The Two Primary Override Techniques

Odoo developers primarily use two methods to override controller functions, each suited for different scenarios.

Supering a Function (Extension)

This is the most common and recommended approach. It allows you to add new behavior to an existing function without fully rewriting it. You call the original function using super() and then modify its result.

Example: Adding a Custom Value to the Product Page Context

Let's add a promotional message to the product page by extending the _prepare_product_values method.

class ExtendedWebsiteSale(WebsiteSale):
    def _prepare_product_values(self, product, category='', search='', **kwargs):
        # First, get all the values from the original method
        result = super()._prepare_product_values(product, category, search, **kwargs)
        
        # Then, add our custom value to the dictionary
        result['special_promo'] = "Free shipping on all orders this week!"
        
        return result

Advantage: This method is safe and maintainable, as it preserves all the existing logic from the parent controller.

Complete Function Overriding (Replacement)

In this approach, you completely redefine the method. This is necessary when you need to fundamentally change the function's logic. You must carefully reimplement any essential behavior from the original function.

Example: Changing the Logic for a Specific Product

class OverriddenWebsiteSale(WebsiteSale):
    @http.route(['/shop/product/<model("product.template"):product>'], type='http', auth="public", website=True, sitemap=sitemap_product)
    def product(self, product, category='', search='', **kwargs):
        # Completely custom logic for product ID 9
        if product.id == 9:
            product.name = "Ergonomic Executive Desk"
        
        # For all other products, we could call super(), but since we overrode completely,
        # we might need to manually handle the template rendering if we don't call the original.
        # This example shows a full override, which is riskier.
        return request.render("website_sale.product", {
            'product': product,
            'add_qty': 1,
            # ... other required context values
        })

Use with Caution: This method can break functionality if the original method's logic changes in future Odoo updates. It should be used sparingly.

Overriding Routed Methods: A Special Consideration

When the method you are overriding is decorated with @http.route, you must include the same decorator in your subclass. The route defines the URL that triggers the method.

Example: Modifying the /shop Page

class CustomWebsiteShop(WebsiteSale):
    @http.route(['/shop', '/shop/page/<int:page>'], type='http', auth="public", website=True)
    def shop(self, page=0, category=None, search='', ppg=False, **post):
        # Call the super method to get the original HTTP response
        response = super().shop(page=page, category=category, search=search, ppg=ppg, **post)
        
        # The response is a Response object. We can access the template context (qcontext)
        # before it is finally rendered.
        if response.qcontext:
            products = response.qcontext.get('products')
            if products:
                for product in products:
                    if product.id == 9:
                        product.name = "Normal Desk"
        
        # Return the modified response
        return response

Key Point: For routed methods, you work with the Response object. The qcontext attribute of this object contains the data dictionary that will be passed to the template, allowing you to modify values before the page is rendered to the user.

Conclusion

Overriding controllers is an essential skill for advanced Odoo 19 development. By understanding the distinction between extending with super() and replacing with a full override, developers can make precise customizations.

  • Prefer super() for adding data or making minor adjustments. It is more resilient to core code changes.
  • Use full overrides judiciously, only when the required change is fundamental and cannot be achieved by extending the original method.
  • Always replicate the @http.route decorator when overriding routed methods to ensure your custom code is triggered by the correct URLs.

Mastering these techniques empowers developers to tailor the Odoo web experience precisely to their business requirements, creating a seamless and fully customized interface for end-users.

To read more about How to Override an Existing Controller in Odoo 18, refer to our blog How to Override an Existing Controller in Odoo 18


If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message