Adding dynamic relations using Reference fields

With relational fields, we need to decide beforehand the relation's target model (or comodel). But sometimes, we may need to leave that decision to the user and first choose the model we want and then the record we want to link to.

With Odoo, this can be achieved using Reference fields.

Getting ready

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

How to do it…

Edit the models/library_book.py file to add the new related field:

  1. We first add a helper method to dynamically build the list of selectable target models:
    from openerp import models, fields, api
    class LibraryBook(models.Model):
        # …
        @api.model
        def _referencable_models(self):
            models = self.env['res.request.link'].search([])
            return [(x.object, x.name) for x in models]
    
  2. Then, we add the Reference field and use the previous function to provide the list of selectable models:
        ref_doc_id = fields.Reference(
            selection='_referencable_models',
            string='Reference Document')

Since we are changing the model's structure, a module upgrade is needed to activate these changes.

How it works…

Reference fields are similar to many-to-one fields, except that they allow the user to select the model to link to.

The target model is selectable from a list provided by the selection attribute. The selection attribute must be a list of two element tuples, where the first is the model internal identifier, and the second is a text description for it.

Here is an example:

[('res.users', 'User'), ('res.partner', 'Partner')]

However, rather than providing a fixed list, we can use a model list configurable by end users. That is the purpose of the built-in Referenceable Models available in the Settings | Technical | Database Structure menu option. This model's internal identifier is res.request.link.

Our recipe started with providing a function to browse all the Model records that can be referenced to dynamically build a list to be provided to the selection attribute. Although both forms are allowed, we declared the function name inside quotes, instead of a direct reference to the function without quotes. This is more flexible, and for example, allows for the referenced function to be defined only later in the code, which is something that is not possible when using a direct reference.

The function needs the @api.model decorator because it operates on the model level, not on the recordset level.

Note

While this feature looks nice, it comes with a significant execution overhead. Displaying the reference fields for a large number of records, for instance, in a list view, can create heavy database loads as each value has to be looked up in a separate query. It is also unable to take advantage of database referential integrity like regular relation fields can.

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

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