Using external IDs and namespaces

There was a lot of talk about XML IDs already, without specifying what an XML ID is. This recipe will give a deeper understanding of this.

How to do it...

We write into already existing records to demonstrate how to use cross module references:

  1. Add a data file to your module manifest:
        'data': [
            'data/res_partner.xml',
        ],
  2. Change the name of our main company:
    <record id="base.main_company" model="res.company">
        <field name="name">Packt publishing</field>
    </record>
  3. Set our main company's partner as publisher:
    <record id="book_cookbook" model="library.book">
        <field name="publisher_id" ref="base.main_partner" />
    </record>

On installation of this module, the company will be renamed and the book from the next recipe will be assigned to our partner. On subsequent updates of our module, only the publisher will be assigned, but the company's name will be left untouched.

How it works...

An XML ID is a string referring to a record in the database. The IDs themselves are records of model ir.model.data. This table's rows contain the module-declaring ID, the identifier string, the referred model, and the referred ID. Every time an ID has to be looked up, Odoo checks whether the string is namespaced already (that is, it contains exactly one dot), and if not adds the current module name as namespace. Then it looks up if there is already a record in ir.model.data with the specified name. If so, an UPDATE statement for the listed fields is executed; if not, a CREATE statement is executed. This is why you can give partial data when a record already exists, as we did above.

Tip

A widespread application for partial data, apart from changing records defined by other modules, is using a shortcut element to create a record in a convenient way and writing a field on this record which is not supported by the shortcut element:

<act_window id="my_action" name="My action"
            model="res.partner" />
<record id="my_action" model="ir.actions.act_window">
    <field name="auto_search" eval="False" />
</record>

The ref function, as used below in the recipe Loading data using XML files, also adds the current module as namespace if appropriate, but raises an error if the resulting XML ID does not exist already. This also applies to the id attribute if it is not namespaced already.

There's more...

You probably need to access records with an XML ID from your code sooner or later. Use the function self.env.ref() in those cases, which returns a browse record of the referenced record. Note that here, you always have to pass the full XML ID.

See also

Consult the recipe Using the noupdate and forcecreate flags to find out why the company's name is changed only on installation of the module.

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

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