Loading data using XML files

Using Chapter 4, Application Models data model, we'll add a book and an author as demonstration data, while we add a well known publisher as normal data in our module.

How to do it...

Create two XML files and link them in your __openerp__.py manifest file:

  1. Add in a file called data/demo.xml to your manifest, in the demo section:
        'demo': [
            'data/demo.xml',
        ],
  2. Add content to this file:
    <odoo>
        <record id="author_af" model="res.partner">
            <field name="name">Alexandre Fayolle</field>
        </record>
        <record id="author_dr" model="res.partner">
            <field name="name">Daniel Reis</field>
        </record>
        <record id="author_hb" model="res.partner">
            <field name="name">Holger Brunn</field>
        </record>
        <record id="book_cookbook" model="library.book">
            <field name="name">Odoo Cookbook</field>
            <field name="short_name">cookbook</field>
            <field name="date_release">2016-03-01</field>
            <field name="author_ids" eval="[(6, 0, [ref('author_af'), ref('author_dr'), ref('author_hb')])]" />
            <field name="publisher_id" ref="res_partner_packt" />
        </record>
    </odoo>
  3. Add a file called data/res_partner.xml to your manifest, in the data section:
        'data': [
            'data/res_partner.xml',
        ],
  4. Add content to this file:
    <odoo>
        <record id="res_partner_packt" model="res.partner">
            <field name="name">Packt Publishing</field>
            <field name="city">Birmingham</field>
            <field name="country_id" ref="base.uk" />
        </record>
    </odoo>

When you update your module now, you'll see in any case the publisher we created, and, if your database has demo data enabled, as pointed out in Chapter 1, Installing the the Odoo Development Environment, you'll also find this book and its authors.

How it works...

As you've seen above, demo data is technically just the same as normal data. The only difference is that the first is pulled by the demo key in the manifest, the latter by the data key.

To create a record, use the record element, which has the mandatory attributes id and model. For the id attribute, consult the recipe Using external IDs and namespaces; the model attribute refers to a model's _name property.

Then you use the field element to fill columns in the database as defined by the model you named. The model also decides which are the mandatory fields to fill and also possibly defines default values, in which case you don't need to give those fields a value explicitly.

As shown above, the field element can contain its value as simple text in case of scalar values.

For setting up references, there are two possibilities. The simplest is using the ref attribute, which works for many2one fields and just contains the XML ID of the record to be referenced.

For one2many and many2many fields, we need to resort to the eval attribute. This is a general purpose attribute that can be used to evaluate Python code to use as the field's value - think of strftime('%Y-01-01') as an example - to populate a date field. X2many fields expect to be populated by a list of 3-tuples, where the first value of the tuple determines the operation to be carried out. Within an eval attribute, we have access to a function called ref, which returns the database ID of an XML ID given as a string. This allows us to refer to a record without knowing its concrete ID, which is probably different per database, as explained in the following:

  • (2, id, False) deletes the linked record with id from the database, the third element of the tuple is ignored.
  • (3, id, False) only cuts the link to a record with id, but leaves the existing record as it is. Here also, the last element of the tuple is ignored.
  • (4, id, False) adds a link to the existing record id, the last element of the tuple is ignored too. This should be what you use most of the time, usually accompanied by using the ref function to get the database ID of a record known by its XML ID.
  • (5, False, False) only works for many2many fields and cuts all links, but keeps the linked records intact.
  • (6, False, [id, …]) only works for many2many fields and first clears out currently referenced records to replace them with the ones mentioned in the list of IDs. The second element of the tuple is ignored.

Note

Note that order matters in data files and that records within data files can only refer to records defined in data files earlier in the list. This is why you should always check if your module installs in an empty database, because during development, it often happens that you add records all over the place, which works because the records defined afterwards are already in the database from a previous update.

Demo data is always loaded after the files from the data key, which is why the reference in the example works.

There's more...

While you can do basically anything with the record element, there are shortcut elements defined that make it more convenient for the developer to create certain kinds of records. Examples are menuitem, template or act window. Refer to Chapter 8, Backend Views and Chapter 14, CMS Website Development for information about those.

A field element can also contain the function element, which calls a function defined on a model to provide a field's value. See the recipe Using the noupdate and forcecreate flags for an application where we simply call a function to directly write to the database, circumventing the loading mechanism.

The above list misses out entries for 0 and 1, because they are not very useful when loading data. They are entered as follows for the sake of completeness:

  • (0, False, {'key': value}) creates a new record of the referenced model, with its fields filled from the dictionary at position three. The second element of the tuple is ignored. As those records don't have an XML ID and are evaluated every time the module is updated, leading to double entries, it's better in general to avoid this, create the record in its own record element, and link it as will be explained later.
  • (1, id, {'key': value}) can be used to write on an existing linked record. For the same reasons as above, you should avoid this syntax.

You will use both of them extensively in Chapter 5, Basic Server Side Business Logic.

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

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