Development Book V17: Data loading

XML Files

In Odoo, data records can be defined using XML files. XML files will be used to store the data. First, we must build a directory named data within the module. Data.xml files are frequently created under the directory data. Let's look at how to construct partner data with XML files. To do this, let us construct a new module named custom_contacts, which will contain a new directory called data. Create an XML file called res_partner_data.xml in the data directory. The record data may be loaded using an XML file by following the syntax below.

<record model="model.name" id="record_id">
    <field name="field_name">field_data </field>
</record>

To create a record, all mandatory fields must be filled out. Using the XML code shown below, we can construct a partner record. The record tag is used to make the record. The record tag can have two attribute values: id and model. 'Id' is the XML record's unique identifier. The 'Model' parameter indicates the model in which the record is being generated. We are creating a new record in the Contacts model in this example, the model is specified as res.partner. Each field value is specified within the record using the field tag shown below. The Name defines the field's technical name, and after that, the field value is given.

<odoo>
    <data>
        <record id="partner_1" model="res.partner"> 
            <field name="name">Aby Wills</field>
            <field name="phone">9865432344</field>
            <field name="email">aby@example.com</field>
        </record>
    </data>
</odoo>

After making the data.xml file, add it in the __manifest__.py file as shown below.

'data' : [
    'data/res_partner_data.xml'
]

Install the custom_contacts module after you've configured it. After installing the module, a partner data with the specified values will be created in the database.

CSV Files

When importing significant amounts of data, CSV files are needed since XML files may not be sufficient. CSV files are used in Odoo source modules. They are mostly used to define access rights. When working with CSV files, There are some important points to remember.

  • The name of this file should be model_name.csv, "ir.model.access.csv," for example. The model name for the access rights is ir.model.access.CSV files are also included within the manifest.
  • The fields that need to be written into will be listed in the first row of the CSV file, along with a field id for the external ID (used for creation or updating).

Let's look at this with an example. Consider the account.tax.group.csv file for this.

id,name,country_id/id
tax_group_0,TVA 0%,base.lu 
tax_group_3,TVA 3%,base.lu 
tax_group_6,TVA 6%,base.lu
tax_group_8,TVA 8%,base.lu
tax_group_10,TVA 10%,base.lu
tax_group_12,TVA 12%,base.lu
tax_group_14,TVA 14%,base.lu
tax_group_15,TVA 15%,base.lu
tax_group_17,TVA 17%,base.lu

The first row defines the fields, which are then followed by values. As a result, when you install the module that includes this CSV file, the relevant records in the model account.tax.group will be created.

No Update

In Odoo, the tag has an attribute called No Update. When a module is updating, this parameter is used to indicate that the values in the XML file need to be recreated. The contents of data files may only be applied once in certain situations. We can set the noupdate attribute to 1 at that point. Here is an example of a noupdate:

<odoo>
    <data noupdate="1">
        <record id="res_partner_data" model="res.partner">
            <field name="name">Demo Partner</field>
            <field name="email">demo@gmail.com</field>
        </record>
    </data>
</odoo>

In the model res.partner, a partner Demo Partner is created during module installation. During the module update, any modifications we created for the record will not have an impact. This means that in the code above, the email and name will remain unchanged even if we change it and upgrade the module.

Force Create

Similar to 'noupdate,' the 'forcecreate' is also an attribute of the tag. When you use this attribute, you ensure that the record is created if it doesn't already exist. The 'forcecreate' attribute is true on by default. This also needs an external ID for the record to make this work. Let's look at an example for better understanding:

<record forcecreate="True" id="decimal_payment" model="decimal.precision">
    <field name="name">Payment Terms</field> 
    <field name="digits">6</field>
</record>

Here, if there is no record found in the model decimal.precision with external id decimal_payment, a new record will be created.

External IDs

An External ID is basically a special name that helps identify a particular record in an XML file. They are also called as XML IDs.These are records of the model ir.model.data which are imported in the case of importing data in Odoo.

When we are importing data using XML IDs, it initially checks for the existence of a record with the same identifier. If there is an existing record with the XML ID, then the UPDATE process will be worked. Otherwise, the CREATE operation will be processed. Usually, XML IDs will be the combination of the record ID and the module name.

E.g., sale.mail_act_sale_upsell

We can update any XML record if the external ID is known. Consider the below as an example.

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data noupdate="1">
        <record id="base.main_company" model="res.company">
            <field name="name">My Company (San Francisco)</field>
        </record>
    </data>
</odoo>

Here the ID of the record is given as XML ID of the main company.Since there is a record with this XML ID, update operation will be performed, resulting in the name changing of the main company.The name field value will be updated to “My Company (San Francisco). There is an option to get the External ID of any records from the User Interface. After enabling debug mode, the developer tool menu will be shown. There is an option to see the metadata of the record from here. External ID is shown inside the metadata.

Namespaces

In Odoo, namespaced phrases refer to external IDs that contain exactly one dot (.). Namespacing is a way to organize and uniquely identify records, and it helps prevent naming conflicts between different modules. When using the external ID for a record tag, Odoo first checks if it is namespaced. That is, if it contains exactly one dot. If it is not namespaced, then Odoo adds the module name as the namespace for the record. Here's an example of namespaced phrases for an external ID:

<record id="module_name.external_id" model="ir.model.data">
    <field name="name">module_name.external_id</field>
    <field name="model">your.model</field>
    <field name="res_id">your_record_id</field>
</record>

In this example:

  • module_name is the namespace.
  • external_id is the specific name or identifier for the record within that namespace.

When Odoo encounters an external ID like module_name.external_id, it understands that module_name is the module providing this record. If you don't provide a namespace (i.e., if the external ID doesn't contain a dot), Odoo assumes the record belongs to the current module, and it automatically adds the module name as the namespace.

Delete Data from XML

Let’s delve into the details of how to delete records from XML in Odoo. When working with Odoo, you might encounter scenarios where you need to remove previously created records during module installation. The <delete> tag comes in handy for this purpose. There are two methods to achieve this:

  1. Using XML ID
  2. Using Search Domain

Using XML ID

In this method, you specify the XML ID of the records you want to delete.

The syntax is as follows:

                        <delete model="your model name" id="XML ID of the record"/> 
                        

Here:

  • your_model_name refers to the model where the record exists,
  • XML_ID_of_the_record is the unique identifier assigned to the record during its creation from another module’s data files.

Odoo will search for the record using the provided XML ID. If found, it will delete the corresponding record. If no matching record is found, an error will be raised. Note that you can only delete records created from XML files (those with XML IDs).

<record id="demo_category_1" model="product.category">
    <field name="name">Category 1</field>
</record>

For example, to delete this record, you have to follow the steps below.

                        <delete model = "product.category" id = "demo_category_1"/> 
                        

Using Search Domain

In this method, you define a search domain to identify records for deletion. Specify the domain using the domain attribute. During module installation, Odoo will search for records based on the given domain. If matching records are found, they will be deleted. Unlike the first method, this approach won’t raise an error if no records match the specified domain. However, be cautious, as it can delete user data. The syntax is as follows:

<delete model = "model_name" search="domain"/>

Let us discuss the syntax with an example.

                        <delete model = "sale.order" search='[(partner_id.name,'=','Azure Interior')]'/>
                        

By executing the provided code, Odoo will remove all Sale Orders associated with the partner named Azure Interior. Commonly delete is rarely used in Odoo.

Function call from XML

Once a module is installed, you may be required to perform certain functions or methods. Odoo allows you to call a function from XML. The tag is used to execute Python functions directly from XML. There are two methods for calling a function from XML.

  • Invoking function without parametersInvoking function without parameters
  • Invoking function with parameters

Invoking function without parameters

We can use this method to call a function defined within any model without passing any parameters. The syntax is provided below

                        <function id="function_id" model="model_name" name="method_name"/> 
                        

The model of the method is specified in the function tag's attribute model. Other attributes include id and name. The id specifies the XML record's unique identifier, and the name corresponds to the method name.

Let's look at a function call without parameters.

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data noupdate="1">
        <function id="func_call_without_params" model="product.product" name="func_without_params"/>
    </data>
</odoo>

The model in this case is product.product. As a result, the system will call the method func_call_without_params, which is defined in the model product.product. As a result, the method definition will be as follows.

from odoo import api, fields, models
class product(models.Model):
_inherit = "product.product"

@api.model
def func_without_params(self):
self.create(dict(name='Test'))

After including the XML data file in the manifest, the method will be called when the module is installed, and a new record will be created in the model product.product.

Invoking function with parameters

The following method is to call a function with parameters. We can use this method to call a function defined within any model while passing parameters. The syntax is slightly different than the previous one, and it is provided below.

<function id="function_id" model="model_name" name="method_name">
    <value>param1</value>
    <value>param2</value>
    <!-- pass the parameters as per your need-->
</function>

The method's parameters are passed inside the value tag. It is possible to pass as many parameters as you require. These parameters are accessible via the model's method. An example is provided below

<odoo>
    <data noupdate="1">
         <function id="func_call_with_params" model="product.product" name="func_with_params">
             <value>Cybrosys Technologies</value>
         </function>
    </data>
</odoo>

Also, we can pass parameters like the below code:

                        <value eval="[('name', '=', 'name_here'), ('module', '=', 'product')]" />
                        

In summary, the eval attribute in the <value> tag is used to evaluate domain expressions and other Python expressions dynamically. It allows to set the values in XML without the need for hardcoding

The method definition should then be as follows.

from odoo import api, fields, models
class product(models.Model):
    _inherit = "product.product"

@api.model
def func_with_params(self, name):
self.create(dict(name=name))

Then include the XML file within the manifest. The Python function will be called when the custom module is installed. The parameter's value will be retrieved and used to create the new product record.

whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message