More on using inheritance to extend models

We have seen the basic in place extension of models, which is also the most frequent use of inheritance. But inheritance using the _inherit attribute has more powerful capabilities, such as mixin classes.

We also have available the delegation inheritance method, using the _inherits attribute. It allows for a model to contain other models in a transparent way for the observer, while behind the scenes each model is handling its own data.

Let's explore these possibilities in more detail.

Copying features using prototype inheritance

The method we used before to extend a model used just the _inherit attribute. We defined a class inheriting the todo.task model, and added some features to it. The class _name was not explicitly set; implicitly it was todo.task also.

But using the _name attribute allows us to create mixin classes, by setting it to the model we want to extend. Here is an example:

from openerp import models
class TodoTask(models.Model):
  _name = 'todo.task'
  _inherit = 'mail.thread'

This extends the todo.task model by copying to it the features of the mail.thread model. The mail.thread model implements the Odoo messages and followers features, and is reusable, so that it's easy to add those features to any model.

Copying means that the inherited methods and fields will also be available in the inheriting model. For fields this means that they will be also created and stored in the target model's database tables. The data records of the original (inherited) and the new (inheriting) models are kept unrelated. Only the definitions are shared.

These mixins are mostly used with abstract models, such as the mail.thread used in the example. Abstract models are just like regular models except that no database representation is created for them. They act like templates, describing fields and logic to be reused in regular models. The fields they define will only be created on those regular models inheriting from them. In a moment we will discuss in detail how to use this to add mail.thread and its social networking features to our module. In practice when using mixins we rarely inherit from regular models, because this causes duplication of the same data structures.

Odoo provides the delegation inheritance mechanism, which avoids data structure duplication, so it is usually preferred when inheriting from regular models. Let's look at it in more detail.

Embedding models using delegation inheritance

Delegation inheritance is the less frequently used model extension method, but it can provide very convenient solutions. It is used through the _inherits attribute (note the additional -s) with a dictionary mapping inherited models with fields linking to them.

A good example of this is the standard Users model, res.users, that has a Partner model embedded in it:

from openerp import models, fields
class User(models.Model):
  _name = 'res.users'
  _inherits = {'res.partner': 'partner_id'}
  partner_id = fields.Many2one('res.partner')

With delegation inheritance the model res.users embeds the inherited model res.partner, so that when a new User is created, a partner is also created and a reference to it is kept in the partner_id field of the User. It is similar to the polymorphism concept in object oriented programming.

All fields of the inherited model, Partner, are available as if they were User fields, through the delegation mechanism. For example, the partner name and address fields are exposed as User fields, but in fact they are being stored in the linked Partner model, and no data structure duplication occurs.

The advantage of this, compared to prototype inheritance, is that there is no need to repeat data structures in many tables, such as addresses. Any new model that needs to include an address can delegate that to an embedded Partner model. And if modifications are introduced in the partner address fields or validations, these are immediately available to all the models embedding it!

Note

Note that with delegation inheritance, fields are inherited, but methods are not.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset