Odoo provides a highly adaptable framework where inheritance plays a key role in customizing and extending the system. Instead of changing the core code, developers can build on top of existing logic, ensuring smooth upgrades and long-term stability. With inheritance, it becomes possible to refine models, adjust views, or add new functionality while keeping the base structure intact. Odoo mainly supports three approaches to inheritance—Python, model, and view inheritance—each serving different customization needs and offering flexibility to match business processes.
1. Python Inheritance
In Odoo, every model automatically inherits from models.Model, which provides access to Odoo's core features like Create, Read, Update, and Delete (CRUD). Inheritance allows you to:
- Add new fields to an existing model.
- Override or extend built-in methods like create, write, or unlink.
- Inject custom logic before or after Odoo performs an action.
This makes it easy to build custom functionality while maintaining a clean separation from the base code.
from odoo import api, fields, models
class NewModel(models.Model):
_name = "new.model"
_description = "New Model"
name = fields.Char(string="Name")
description = fields.Text(string="Description")
@api.model
def create(self, vals):
if not vals.get('description'):
vals['description'] = 'Auto-generated description'
return super(NewModel, self).create(vals)
In the example above, we create a new model called new.model. The create() method is overridden to check whether the description field is provided. If it's missing, we set a default description before calling the original create() method using super().
2. Model Inheritance
In Odoo, inheritance is implemented through three specialized mechanisms, each designed with a clear purpose. Classical inheritance allows developers to enhance and reuse existing models. Extension inheritance makes it possible to prototype or define entirely new entities, and Delegation inheritance provides a way to build relationships by linking models together. Recognizing the strengths of each approach is essential for creating scalable, maintainable, and future-ready business applications in Odoo.
Classical Inheritance
To implement classical inheritance, you define both the _name and _inherit attributes in the new model. The _inherit points to the existing model you want to inherit from, and _name declares the identity of the new model.
from odoo import fields, models
class Vehicle(models.Model):
_name = 'garage.vehicle'
_description = 'Vehicle'
name = fields.Char(string='Vehicle Name')
speed = fields.Integer(string='Top Speed (km/h)')
def move(self):
return f"{self.name} is moving at {self.speed} km/h."
class Car(models.Model):
_name = 'garage.car'
_inherit = 'garage.vehicle'
_description = 'Car'
number_of_doors = fields.Integer(string='Number of Doors')
def move(self):
return f"{self.name} is driving smoothly at {self.speed} km/h."
Extension Inheritance
It is a technique in Odoo where you extend an existing model by adding new fields or overriding its methods. Unlike classical inheritance (where you define a new model with _name), extension inheritance works by specifying only the _inherit attribute — pointing to the model you want to extend.
from odoo import models, fields
class ResPartner(models.Model):
_inherit = 'res.partner'
loyalty_points = fields.Integer(string='Loyalty Points')
Delegation Inheritance
Delegation inheritance allows you to reuse the fields of another model by creating a Many2one link to that model and delegating access to its fields. Your model will have its own database table, but you can access the fields of the linked model as if they were part of yours.
from odoo import models, fields
class Book(models.Model):
_name = 'book.book'
_description = 'Book'
title = fields.Char(string='Title')
author = fields.Char(string='Author')
class LibraryBook(models.Model):
_name = 'library.book'
_inherits = {'book.book': 'book_id'}
_description = 'Library Book'
book_id = fields.Many2one('book.book', required=True, ondelete='cascade')
shelf_number = fields.Char(string='Shelf Number')
3. View Inheritance
In Odoo, just like models, views can also be inherited and extended. This is done using View Inheritance, a mechanism that lets developers modify existing form, list, kanban, or search views using XML.
<odoo>
<record id="view_partner_form_inherit" model="ir.ui.view">
<field name="name">res.partner.form.inherit.membership</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='category_id']" position="after">
<field name="membership_id"/>
</xpath>
</field>
</record>
</odoo>
4. Controller Inheritance
Controllers in Odoo are Python classes that handle HTTP requests (both backend and website). They are defined in odoo.http and extended with @http.route.
Suppose you want to extend Odoo’s default website sale shop page (/shop).
from odoo import http
from odoo.http import request
from odoo.addons.website_sale.controllers.main import WebsiteSale
class WebsiteSaleInherit(WebsiteSale): # inherit existing controller
@http.route(['/shop'], type='http', auth="public", website=True)
def shop(self, **kwargs):
response = super(WebsiteSaleInherit, self).shop(**kwargs)
print("Custom shop logic executed")
return response
Here, we are inheriting the existing shop route and adding custom behavior.
5. Inheriting Reports
In Odoo 19, reports are one of the most common areas that developers and businesses want to customize. Whether it’s invoices, sales orders, or delivery slips, Odoo gives you a powerful way to modify reports without touching the core code: Report Inheritance.
Every report in Odoo has two main components:
Report Action (ir.actions.report)
- Defines the report (name, model, output type, and template).
QWeb Template
- The XML layout that controls how the report looks when rendered (PDF or HTML).
Consider a Customer Invoice Report
First, find the report template you want to extend (for example, account.report_invoice_document for invoices).
Inherit the report to add a custom note to invoices without modifying the core file:
<template id="report_invoice_add_footer"
inherit_id="account.report_invoice_document">
<xpath expr="//div[@class='page']" position="after">
<div class="footer-note">
<p>This invoice is system-generated and does not require a signature.</p>
</div>
</xpath>
</template>
6. Extending Workflow in Odoo 19
Extending Workflow in Odoo 19 means adding or modifying business process stages using states, buttons, or automated actions; for example, adding a new “Quality Check” state to sale.order with a button to move the order to that state:
from odoo import models, fields, api
class SaleOrder(models.Model):
_inherit = 'sale.order'
state = fields.Selection(selection_add=[('quality_check', 'Quality Check')])
def action_quality_check(self):
for order in self:
order.state = 'quality_check'
<record id="view_order_form_inherit" model="ir.ui.view">
<field name="name">sale.order.form.workflow.inherit</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//header" position="inside">
<button name="action_quality_check" string="Quality Check" type="object"
invisible=”state != ‘sale’”/>
</xpath>
</field>
</record>
Inheritance in Odoo 19 is a core concept that empowers developers to write clean, modular, and upgrade-safe code. Whether you're building new models, extending existing ones, or customizing the user interface, Odoo provides flexible inheritance mechanisms tailored to every need.
Here’s a quick recap:
- Classical Inheritance allows you to create a new model based on an existing one, reusing fields and methods while defining a separate identity.
- Extension Inheritance lets you modify or extend an existing model directly—ideal for adding fields or overriding methods.
- Delegation Inheritance enables your model to reuse fields from another model via a Many2one link while maintaining separate database tables.
- Controller Inheritance extends or overrides existing backend/website routes by inheriting controller classes and using super() for original logic.
- Report Inheritance safely customizes QWeb reports using inherit_id and xpath to add, replace, or remove elements without modifying core templates.
- Extended Workflows add or modify business process stages using states, buttons, and automated actions to extend model workflows in a modular, upgrade-safe way.
By understanding and applying these inheritance types properly, you can build powerful, maintainable, and scalable Odoo applications—while keeping your codebase aligned with best practices.
To read more about What are the Different Types of Inheritance in Odoo 18, refer to our blog What are the Different Types of Inheritance in Odoo 18.