In this blog, we can discuss the technical tips which are useful during the module development of odoo 13.
1. Module structure using scaffold
2. Module installation and upgrade from terminal
3. Storing and retrieving values from res.config.settings
4. Tree view improvements
5. Some field properties
Module Structure Building
We can build a basic structure of our custom module by using a single line of code
with the help of the scaffold.
python3 odoo-bin scaffold module_name destination_folder_name
Here if the command running directory is the same as the source directory of odoo-bin then you can use the above code. If the source directory of odoo-bin different from the command running directory then also provides the path of the odoo-bin too.
For example
python3 odoo-bin scaffold real_estate_management anonymous
The above code will create a module named real_estate_management in the folder anonymous.
Module Installation and Upgrade
Installing a module from the terminal using the command.
./odoo-bin -c conf_file -i module_name -d database_name
Here we have to specify the path to the odoo-bin,conf_file, module name, and database name. If the command is running from the source directory of the odoo-bin and conf file, you can directly give the name of the files.
For example
./odoo-bin -c odoo-12.conf -i vendor_bill_report_xml -d xml_report_verifying
Upgrading a module from the terminal using the command
./odoo-bin -c your_conf_file -u module_name -d database_name
For example
./odoo-bin -c odoo-12.conf -u vendor_bill_report_xml -d xml_report_v12
How can we restart the service automatically when changes occur in the python file.
This can be possible using an extra python package called watchdog.
The configuration is- just add –dev=reload in the parameters of configuration in pycharm.
And we can see the addons that are under watching in the log.
Usages of res.config.settings
Storing values in res.config.settings.
Consider the following example of storing a Many2one field of res.partner in res.config.settings.
partner = fields.Many2one('res.partner')@api.modeldef get_values(self):res = super(ResConfigSettings, self).get_values()params = self.env['ir.config_parameter'].sudo()partner = params.get_param('partner', default=False)res.update(partner=int(partner),)return res@api.multidef set_values(self):super(ResConfigSettings, self).set_values()self.env['ir.config_parameter'].sudo().set_param("partner", self.partner.id)
Retrieving values from res.config.settings
Consider the below example:
class ResConfigSettings(models.TransientModel):_inherit = 'res.config.settings'partner_id = fields.Many2one('res.partner',string='Partner')
If we want to retrieve the above value stored in res.config.settings from any other models, use the code below
settings_partner = self.env['ir.config_parameter'].sudo().get_param('partner_id') or False
Installing and uninstalling modules based on a boolean field in res.config.settings.
We have to add a boolean field in res.config.settings for the dependent module. The boolean field will be in a defined format. eg If we want to install/uninstall sale_management module based on a boolean field then the field will be as follows:
module_sale_management = fields.Boolean(string='Install/Uninstall sale management')
Building settings for a custom module
Steps included
> Inheriting res.config.settings and adding required fields.
class Settings(models.TransientModel):_inherit = 'res.config.settings'your_custom_field = fields.Boolean(default=False)
> Define the form view in res.config.settings.
<record id="view_res_config_settings" model="ir.ui.view"><field name="name">module_name.res.config.settings.form</field><field name="model">res.config.settings</field><field name="inherit_id" ref="base.res_config_settings_view_form"/><field name="arch" type="xml"><xpath expr="//div[hasclass('settings')]" position="inside"><div class="app_settings_block" data-string="Demo Module" string="Demo Module"data-key="module_name"groups="required_group_id"><!--You custom codes for displaying the fields--></div></xpath></field></record><record id="action_your_module_name_settings" model="ir.actions.act_window"><field name="name">Settings</field><field name="type">ir.actions.act_window</field><field name="res_model">res.config.settings</field><field name="view_mode">form</field><field name="target">inline</field><field name="context">{'module' : 'your_module_name'}</field></record><menuitem id="menu_your_module_name_settings" name="Demo Module"/><menuitem id="your_module_name.menu_your_module_name_settings" name="Configuration"parent="menu_your_module_name_settings"sequence="99" action="action_your_module_name_settings"/>
Tree view Improvements
> Disable the import button by
<tree import="0"/>
> Enable the mass editing in the tree view by
<tree string="Lots/Serial Numbers" multi_edit="1">
> Creating dynamic tree view(Hide/Show the fields dynamically from Odoo)
Just assign optional=”show” or optional=”hide”
<tree string="Lots/Serial Numbers" multi_edit="1"><field name="name"/><field name="ref" optional="show"/><field name="product_id" optional="hide"/><field name="create_date" optional="show"/><field name="company_id" groups="base.group_multi_company"/></tree>
Some Field Properties
> Making a field visible in debug mode only
<field name="your_field_name" groups="base.group_no_one"/>
> Making an Integer field with increment/decrement options
<field name="your_field_name" options='{"type": "number"}' string="Your field string"/>
If you need to change the steps of increment and decrement the define the options like below
<field name="your_field_name" options='{"type": "number","step": number of steps}' string="Your field string"/>
> Converting a field into button and which act as selection button in a predefined set of range
<field name="street" widget="float_toggle" options='{"range":[1,2,3]}'/>