The modular architecture of Odoo provides the possibility of customization and enhancements without changes in the core. In addition, this makes the software upgrade easier because of keeping customizations consistent. There are many techniques Odoo users can utilize to accomplish this task. One of the most important techniques is the extension inheritance technique, where you use the _inherit field. The difference between this technique and the creation of entirely new models or the linking of other tables is that here you can simply enhance your models without recreating them from scratch. In this blog post, we'll look into what extension inheritance is, how it is implemented, and when it is needed.
What is Extension Inheritance?
Extension inheritance is one of the tools that lets us create a model based on another model, extending its features with new fields, methods, or overwriting its existing ones, without having to create a new model or modify anything about the existing one. The main distinction between extension inheritance and classical inheritance lies in the fact that, here,
We do not provide the _name parameter but only provide the _inherit parameter.
As we work with extension inheritance, we actually customize our model, which means all changes will be implemented inside this model without creating a new one or creating a new database table; we merely add new columns to our already existing table.
How Extension Inheritance Works
In Odoo, inheritance by extension occurs when there is a definition of a class, where its parent is defined as models.Model. The class must have the parameter called _inherit, which specifies that a specific model should be extended.
Here's the basic syntax:
from odoo import models, fields
class ExtendedModel(models.Model):
_inherit = 'existing.model'
# Your customizations here
Once your module is loaded in Odoo, it knows that you are trying to extend the existing.model and makes changes in it. Any new fields defined will be included in the database table of the model, and any new methods will either override or extend the original ones.
Example: Extension Inheritance in Action
Let's look at practical examples of how extension inheritance can be used in Odoo 19.
Example 1: Adding New Fields to an Existing Model
Suppose you want to add a loyalty points system to customer records. Instead of creating a new model, you can extend the existing res.partner model:
from odoo import models, fields
class ResPartner(models.Model):
_inherit = 'res.partner'
loyalty_points = fields.Integer(string='Loyalty Points', default=0)
membership_level = fields.Selection([
('bronze', 'Bronze'),
('silver', 'Silver'),
('gold', 'Gold'),
('platinum', 'Platinum')
], string='Membership Level', default='bronze')
last_purchase_date = fields.Date(string='Last Purchase Date')
Now, every partner record in your database will have these new fields, and you can use them in forms, reports, and business logic.
Example 2: Overriding Methods
You may also customize existing functions by overriding them to implement additional business logic. For example, we can extend the function create of sale.order to assign an auto-generated reference number:
from odoo import api, models, fields
class SaleOrder(models.Model):
_inherit = 'sale.order'
custom_reference = fields.Char(string='Custom Reference', readonly=True)
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
# Generate a custom reference before creating the order
if not vals.get('custom_reference'):
vals['custom_reference'] = self.env['ir.sequence'].next_by_code('sale.order.custom') or '/'
return super(SaleOrder, self).create(vals)
The above code captures every call to the creation of sale orders, assigns a unique reference number, and invokes the original create function via super().
Example 3: Adding Computed Fields and Logic
Extension inheritance is perfect for adding computed fields and related business logic:
from odoo import api, models, fields
class ProductTemplate(models.Model):
_inherit = 'product.template'
total_stock_value = fields.Float(
string='Total Stock Value',
compute='_compute_total_stock_value',
store=True
)
is_low_stock = fields.Boolean(
string='Low Stock Alert',
compute='_compute_low_stock'
)
@api.depends('qty_available', 'list_price')
def _compute_total_stock_value(self):
for product in self:
product.total_stock_value = product.qty_available * product.list_price
@api.depends('qty_available')
def _compute_low_stock(self):
for product in self:
product.is_low_stock = product.qty_available < 10
Example 4: Adding Constraints and Validations
You can also add custom validation rules to existing models:
from odoo import api, models, fields
from odoo.exceptions import ValidationError
class ResPartner(models.Model):
_inherit = 'res.partner'
tax_id = fields.Char(string='Tax ID')
@api.constrains('tax_id')
def _check_tax_id_format(self):
for partner in self:
if partner.tax_id and len(partner.tax_id) < 9:
raise ValidationError("Tax ID must be at least 9 characters long.")
When to Use Extension Inheritance
Extension inheritance is the right choice when you want to:
- Add new fields to standard Odoo models without creating separate tables or relationships.
- Add computed fields, constraints, or validation rules to existing models.
- Extend models from other custom modules to ensure compatibility and modularity.
- Keep customizations upgrade-safe by avoiding direct modifications to core code.
Extension inheritance is particularly useful when:
- You need to store additional information directly on existing records.
- Your customizations are tightly coupled with the base model's functionality.
- You want changes to be immediately available across all existing views and reports.
- You're building on top of Odoo's standard modules or third-party modules.
Inheritance via extensions is probably the strongest, as well as the most widely utilized, tool that Odoo developers have at their disposal. Using extensions' inheritance capabilities, you can easily extend any model's functionality by adding new fields, changing methods, and creating additional business logic right inside already existing modules. This makes it possible to customize Odoo without any changes to its base code, thus avoiding all possible pitfalls connected with future upgrades.
Whether you need to add a simple field for storing customer preferences or some intricate logic for validating sales order information, inheritance through extensions is always there to provide you with the perfect solution.
To find out what the other types of inheritance Odoo 18 has, visit the blog post What are the Different Types of Inheritance in Odoo 18?
To read more about Overview of Delegation Inheritance (_inherits) in Odoo 19, refer to our blog Overview of Delegation Inheritance (_inherits) in Odoo 19.