Difference Between _inherit vs _inherits in Odoo?

✅ What Are They?

Both _inherits and _inherit are used to extend existing models in Odoo, but they work differently:
 
Feature
_inherit
_inherits
Inheritance Classical Odoo inheritance Delegation inheritance
DB Structure Works on same table (shared) Works on multiple tables (linked)
Use Case Extend behavior or add fields Compose new models using others
Field Access Direct Delegated via foreign key

 📌 Realistic  Examples : Sales Summary by Customer

1. _inherit: Classic Inheritance
📌 Use Case:
Used when you want to add fields or override logic in an existing model like res.partner, sale.order, etc.

🔧 Example:

class InheritPartner(models.Model):

    _inherit = ‘res.partner’

    loyalty_points = fields.Integer(string=“Loyalty Points”)

    def custom_method(self):

        # extending existing method

        pass

✅ This will add a new field directly to the res.partner table.

2. _inherits: Delegated Inheritance

📌 Use Case:

Used when you want to reuse another model’s fields and data but store your own fields in a separate table.

🔧 Example:

class StudentRecord(models.Model):

    _name = ‘student.record’

    _inherits = {‘res.partner’: ‘partner_id’}


    partner_id = fields.Many2one(‘res.partner’, required=True, ondelete=‘cascade’)

    student_code = fields.Char(string=‘Student Code’)

⚠️ Key Points

Concept
Details
_auto = False Prevents Odoo from creating a DB table.
init() method Used to manually create SQL view via raw SQL.
tools.drop_view_if_exists() Utility to safely recreate views on module upgrade.
id field Must be present and unique in the view for Odoo to work properly.

✅ This allows you to:

  • Store student-specific data in student.record
  • Reuse all res.partner fields as if they belong to student.record
So:

student = self.env[‘student.record’].browse(1)

print(student.name)  # from res.partner

print(student.student_code)  # from student.record

⚠️ The record will be stored in two tables, linked by the partner_id.

🎯 When to Use What?

Use Case
Use _inherit
Use _inherits
Extend existing model’s features ✅ Yes 🚫 No
Combine models like composition 🚫 No ✅ Yes
Need separate table and identity 🚫 No ✅ Yes
Add or override methods ✅ Yes 🚫 Limited

⚙️ Internal Difference

Feature
_inherit
_inherits
Field resolution From current model/table Redirected to foreign model via M2O
Record identity Same record ID and table Separate IDs (joined by foreign key)
DB schema Fields added directly to base model Separate table with relationship

✅ Summary Table

Attribute
Purpose
Storage
Real Use Case
_inherit Extend existing model (fields/methods) Shared table Add extra fields to res.partner
_inherits Reuse another model with linkage Separate table Create student.record from partner

🧠 Developer Tips

  • Use _inherit for 90% of extension work.
  • Use _inherits only when modeling something structurally distinct but sharing core data.
  • Avoid mixing both in the same model unless explicitly required.
  • Be careful with record deletion in _inherits – always set ondelete=’cascade’ for clean joins.