Did you know that in the odoo enterprise version we can change the odoo’s views by drag and drop?
By installing a module named web_studio or commonly called by Odoo Studio we can change the odoo’s views easily. Just open the view that we want to change, open odoo studio, then change the view through the user interface. This is a screenshot of odoo studio on odoo enterprise v14, where I am adding a field with Order Reference label in the Sales Order form.
Unfortunately, if we have created a field in odoo studio, then we want to use that field in the normal module, which is created by creating a folder and some python and xml files, when we install that module an error message will appear, stating the fields that we have created in odoo studio does not exist.
As an example, let’s assume we have created a new field in odoo studio with the name of x_studio_new_field in the sale.order model.
Then suppose we are going to create a new field, in the normal way, without odoo studio, like in the code below.
# -*- coding: utf-8 -*- from odoo import api, fields, models, _, tools class Sale(models.Model): _inherit = 'sale.order' other_new_field = fields.Many2one('product.product')
Then suppose that in the sales order form, we want the other_new_field above to use the domain with the value of the x_studio_new_field, like in the code below.
<record id="view_order_form_inherit" model="ir.ui.view"> <field name="name">view_order_form</field> <field name="model">sale.order</field> <field name="inherit_id" ref="sale.view_order_form" /> <field name="arch" type="xml"> <field name="date_order" position="after"> <field name="other_new_field" domain="[('name','ilike',x_studio_new_field)]" /> </field> </field> </record>
It turns out that when we install the module that we made in the normal way, this will cause an error. like in the image below.
The full error message says : Field x_studio_new_field used in domain of <field name=”other_new_field”> ([(‘name’,’ilike’,x_studio_new_field)]) must be present in view but is missing.</field>.
In fact, if we search manually in the Settings >> Technical >> User Interface >> Views menu, the x_studio_new_field is already in the view, as shown in the image below.
After I explore in more detail, it turns out that the views created in odoo studio are not automatically loaded by odoo if we install/upgrade the modules that we create normally. Therefore, if the module that we created in the xml file calls the field created in odoo studio it will cause an error. But if the module python file calls a field created in odoo studio, for example in a method, odoo does not show an error message.
So, is there a solution to solve this problem?
When I first encountered this problem, the first step I did was to comment on the contents of the xml file of the module that I created in the normal way. For example like this.
<record id="view_order_form_inherit" model="ir.ui.view"> <field name="name">view_order_form</field> <field name="model">sale.order</field> <field name="inherit_id" ref="sale.view_order_form" /> <field name="arch" type="xml"> <!-- <field name="date_order" position="after"> <field name="other_new_field" domain="[('name','ilike',x_studio_new_field)]" /> </field> --> </field> </record>
In this way when we install/upgrade the module the x_studio_new_field will not be read, because it is commented, so the module can be installed. Then after the module has been successfully installed I will uncomment the xml file above from the Settings >> Technical >> User Interface >> Views menu. It’s a bit tricky, right?
Finally after fiddling arround with the odoo source code I found a better way, it is by adding a load_all_views context in the _check_xml method in the ir.ui.view model. Like in the code below.
# -*- coding: utf-8 -*- from odoo import api, fields, models, _, tools class IrUiView(models.Model): _inherit = 'ir.ui.view' @api.constrains('arch_db') def _check_xml(self): context = dict(self._context) context['load_all_views'] = True return super(IrUiView, self.with_context(context))._check_xml()
Write the above code in a separate module, then install it first before you install/upgrade the module that calls the fields created in odoo studio. Or you can download the ready to use module at this page.
With the load_all_views context all views will be loaded by odoo, whether it is created through odoo studio or the normal way, so the x_studio_new_field can be found in one of the views and the module that we create normally can be install/upgrade successfully.
So far after I tested on odoo v14, this method is quite successful. However, due to the limited time of the test, I can’t be sure that this method has side effects or not. I would really appreciate your help to test and review this method and share the results with me.