What is "No-Update" Functionality?
by Muhammad Kamran
The structure of the Odoo framework allows the creation of records or datasets through Odoo’s generic XML code. The records are supposed to be dummy data to be used for learning processes or default data to control Odoo’s base process like security groups, access rights, record rules, etc. All these data sets are set or coded under no-update functionality.
<data noupdate="1">
The "no-update" functionality is used to prevent the module upgrade process from making changes or updating data defined under a tag with this attribute. Essentially, data entered through code only needs to be updated or added once, and the module may encounter further changes or customisations. Since the framework upgrades all aspects of the module, this data will need to be defined again with every iteration of the module upgrade. To avoid this, Odoo applies the "no-update" attribute functionality.
The second reason for this functionality is to prevent users/developers from making changes to these default records through code. However, in some cases, changes may need to be made to these records, especially when it comes to security records. This can pose a challenge for Odoo developers who face issues when attempting to modify records that are set to no-update in Odoo core addons.
Modifying a Record Set to "No-Update"
Let's take a look at a specific example, consider the scenario in the following path: addons/base/security/base_security.xml. Here, we encounter the same issue as described above, and we attempt to modify the record rules defined in this file.
<record
id="res_partner_rule_private_employee" model="ir.rule">
<field name="name">res.partner.rule.private.employee</field>
<field name="model_id" ref="base.model_res_partner"/>
<field name="domain_force">['|', ('type', '!=', 'private'),
('type', '=', False)]</field>
<field name="groups"
eval="[Command.link(ref('base.group_user')),]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_unlink" eval="True"/>
</record>
Let's try to make changes in the field of domain_force of this record. The first step is to change the update behavior of this file to allow changes that can make a difference. For that purpose, we need to write a function that will change the update behavior. See the code below:
<function
name="write" model="ir.model.data">
<function name="search" model="ir.model.data">
<value eval="[('module', '=', 'base'), ('name', '=',
'res_partner_rule_private_employee')]" />
</function>
<value eval="{'noupdate': False}" />
</function>
The first function is "write" and it operates on the "ir.model.data" model. This function calls another function "search" to find a specific record in the database with the module name "base" and the record name "res_partner_rule_private_employee". The search function takes a list of conditions in the form of a tuple. If the record is found, the write function updates the "noupdate" field with the value False.
Now we will make the changes in the record we want to target. For reference see the code below:
<record
id="base.res_partner_rule_private_employee"
model="ir.rule">
<field name="domain_force">['|', ('type', '!=', 'private'),
('type', '=', False),('category_id','!=',3)]</field>
</record>
Moving on, after making the changes we have to set those values back to their default with the help of following function:
<function name="write" model="ir.model.data"><function name="search" model="ir.model.data">
<value eval="[('module', '=', 'base'), ('name', '=', 'res_partner_rule_private_employee')]" />
</function>
<value eval="{'noupdate': True}" />
</function>