Adding features to a Model using inheritance

One of the most important Odoo features is the ability of module addons extending features defined in other module addons without having to edit the code of the original feature. This might be to add fields or methods, or modify existing fields, or extend existing methods to perform additional logic.

It is the most frequently used method of inheritance and is referred to by the official documentation as traditional inheritance or classical inheritance.

We will extend the built in Partner model to add it to a computed field with the authored book count. This involves adding a field and a method to an existing model.

Getting ready

We will reuse the my_module addon module from Chapter 3, Creating Odoo Modules.

How to do it…

We will be extending the built-in Partner model. We should do this in its own Python code file, but to keep the explanation as simple we can, we will reuse the models/library_book.py code file:

  1. First, we make sure the authored_book_ids inverse relation is in the Partner model and add the computed field:
    class ResPartner(models.Model):
        _inherit = 'res.partner'
        _order = 'name'
        authored_book_ids = fields.Many2many(
            'library.book', string='Authored Books')
        count_books = fields.Integer(
            'Number of Authored Books',
            compute='_compute_count_books'
            )
  2. Next, add the method needed to compute the book count:
    # ...
    from openerp import api  # if not already imported
    # class ResPartner(models.Model):
        # ...
        @api.depends('authored_book_ids')
        def _compute_count_books(self):
            for r in self:
                r.count_books = len(r.authored_book_ids)
    

Finally, we need to upgrade the addon module for the modifications to take effect.

How it works…

When a model class is defined with the _inherit attribute, it adds modifications to the inherited model rather than replacing it.

This means that fields defined in the inheriting class are added or changed on the parent model. At the database layer, it is adding fields on the same database table.

Fields are also incrementally modified. This means that if the field already exists in the super class, only the attributes declared in the inherited class are modified; the other ones are kept as in the parent class.

Methods defined in the inheriting class replace the method in the parent class. So, unless they include a call to the parent's version of the method, we will lose features. Because of this, when we want to add logic to existing methods, they should include a statement with super to call its version in the parent class. This is discussed in more detail in Chapter 5, Basic Server Side Business Log.

There's more…

With the _inherit traditional inheritance, it's also possible to copy the parent model's features into a completely new model. This is done by simply adding a _name model attribute with a different identifier. Here is an example:

class LibraryMember(models.Model):
    _inherit = 'res.partner'
    _name = 'library.member'

The new model has its own database table with its own data totally independent from the res.partner parent model. Since it still inherits from the Partner model, any later modifications to it will also affect the new model.

In the official documentation, this is called prototype inheritance, but in practice, it is seldom used. The reason is that delegation inheritance usually answers to that need in a more efficient way, without the need to duplicate data structures. For more information on it, you can refer to the Use Delegation inheritance to copy features to another Model recipe.

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

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