How to Override an Existing Controller in Odoo 16

How to Override an Existing Controller in Odoo 16

4 minutes, 43 seconds Read

Controllers are used in Odoo to develop front-end modules. Backend modules are linked to the Controllers. We can modify the programming logic or add new logic to the existing program by making modifications to the base class using the overriding property.

In this blog, we are going to talk about how to override an existing controller

To add controllers to the module, as the first step, you have to create a separate directory for the controllers. Inside this directory, an init file and all the python files that contain controller methods should be added to the init file. Then, add this directory to the init file of the module.

How to Override an Existing Controller in Odoo 16-cybrosys

To override a controller, we must first construct a subclass in which the existing function is defined. From this controller, we must then choose a function to override.

We can pick a Carousel function, for instance, and override it.

def _get_products_recently_viewed(self):
   """Returns list of recently viewed products according to current user."""
   max_number_of_product_for_carousel = 12
   visitor = request.env[
       'website.visitor']._get_visitor_from_request()
   if visitor:
       excluded_products = request.website.sale_get_order().mapped(
           'order_line.product_id.id')
       products = request.env['website.track'].sudo().read_group(
           [('visitor_id', '=', visitor.id),
            ('product_id', '!=', False),
            ('product_id.website_published', '=', True),
            ('product_id', 'not in', excluded_products)],
           ['product_id', 'visit_datetime:max'], ['product_id'],
           limit=max_number_of_product_for_carousel,
           orderby='visit_datetime DESC')
       products_ids = [product['product_id'][0] for product in
                       products]
       if products_ids:
           viewed_products = request.env[
               'product.product'].with_context(
               display_default_code=False).browse(products_ids)
       FieldMonetary = request.env['ir.qweb.field.monetary']
       monetary_options = {
           'display_currency': request.website.get_current_pricelist().currency_id,
       }
       rating = request.website.viewref(
           'website_sale.product_comment').active
       res = {'products': []}
       for product in viewed_products:
           combination_info = product._get_combination_info_variant()
           res_product = product.read(['id', 'name', 'website_url'])[
               0]
           res_product.update(combination_info)
           res_product['price'] = FieldMonetary.value_to_html(
               res_product['price'], monetary_options)
           if rating:
               res_product['rating'] = request.env[
                   "ir.ui.view"]._render_template(
                   'portal_rating.rating_widget_stars_static',
                   values={
                       'rating_avg': product.rating_avg,
                       'rating_count': product.rating_count,
                   })
           res['products'].append(res_product)
       return res
   return {}

At first, we need to import the existing class to our overriding file as a library

from Odoo.addons.website_sale.controllers.main import WebsiteSale
from Odoo.http import request

And now, we need to make the necessary modifications inside the subclass that is now overriding, such as adding a function or changing a function by referencing the function that we need to override and making the necessary changes to the function.

The maximum number of products that could be shown in the Carousel in our example was 12, but we are changing that by overriding it to 10.

class ProductsRecentlyViewes(WebsiteSale):
   """Returns list of recently viewed products according to current user."""
   max_number_of_product_for_carousel = 10
   visitor = request.env['website.visitor']._get_visitor_from_request()
   if visitor:
       excluded_products = request.website.sale_get_order().mapped(
           'order_line.product_id.id')
       products = request.env['website.track'].sudo().read_group(
           [('visitor_id', '=', visitor.id), ('product_id', '!=', False),
            ('product_id.website_published', '=', True),
            ('product_id', 'not in', excluded_products)],
           ['product_id', 'visit_datetime:max'], ['product_id'],
           limit=max_number_of_product_for_carousel,
           orderby='visit_datetime DESC')
       product_ids = [product['product_id'][0] for product in products]
       if product_ids:
           viewed_products = request.env['product.product'].with_context(
               display_default_code=False).browse(product_ids)

Currently, instead of 12, only 10 products will be shown in the colossal, according to the website.

When replacing or supering an existing function, we have two primary options for overriding it. These are the things we need to bear in mind. 

a) Function overriding: We copy and paste the parent class’s function to the class we inherited, making the necessary modifications so that the new function completely replaces the old one.

b) Supering a function: this technique is employed when we only need to add a few modifications to a function in order to inherit all of its features and attributes from the parent class.

The syntax of inheriting a class is as given below:

from <path_to_existing_controller> import <ClassName>

For example:

from Odoo.addons.website_sale.controllers.main import WebsiteSale

– The rendered template will provide values in the parameters like qcontent or **kwargs. We just have to use them directly or by editing. If necessary,  qcontext will return the value from the controller, which we may utilize or change.

– If you try to override a controller that includes a route, you can run into problems only if the inherited subclass did not include the route specification. Therefore, the route will need to be mentioned in the inherited subclass, after which you can easily make the needed changes. 

class WebsiteShop(Websitesale):
        @http.route([                                                                                                    
            '/shop',
            '/shop/page/<int:page>',
            '/shop/category/<model("product.public.category"):category>',      '/shop/category/<model("product.public.category"):category>/page/<int:page>',
        ], type='http', auth="public", website=True, sitemap=sitemap_shop)
        def shop(self, page=0, category=None, search='', min_price=0.0,
                 max_price=0.0, ppg=False, **post):
            res = super(WebsiteShop, self).shop(self, page=0, category=None,
                                                search='', min_price=0.0,
                                                max_price=0.0, ppg=False,
                                                **post)
            product = res.qcontext.get(products)
            for rec in product:
                if rec.id == 9:
                    rec.name = 'Normal Desk'
            return res

Here, we use qcontext to override a function and modify a product’s name. In Odoo 16, you can easily override a function in the same way as it is defined in the example above.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *