From 34dd6a2dba15707098349f42a42d4eaa330df098 Mon Sep 17 00:00:00 2001 From: Victor Feyens Date: Mon, 30 Nov 2020 10:15:06 +0000 Subject: [PATCH] [IMP] base: provide a cached method to fetch module records Following the API for ir.model records, the same logic is provided for ir.module.module records. This allows to avoid a bunch of queries when modifying/opening settings. Part-of: odoo/odoo#62249 --- odoo/addons/base/models/ir_module.py | 12 ++++++++++++ odoo/addons/base/models/res_config.py | 14 +++++--------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/odoo/addons/base/models/ir_module.py b/odoo/addons/base/models/ir_module.py index d1f60a07126..5f46b0d88d5 100644 --- a/odoo/addons/base/models/ir_module.py +++ b/odoo/addons/base/models/ir_module.py @@ -935,6 +935,18 @@ class Module(models.Model): if not module.description_html: _logger.warning('module %s: description is empty !', module.name) + def _get(self, name): + """ Return the (sudoed) `ir.module.module` record with the given name. + The result may be an empty recordset if the module is not found. + """ + model_id = self._get_id(name) if name else False + return self.browse(model_id).sudo() + + @tools.ormcache('name') + def _get_id(self, name): + self.env.cr.execute("SELECT id FROM ir_module_module WHERE name=%s", (name,)) + return self.env.cr.fetchone() + @api.model @tools.ormcache() def _installed(self): diff --git a/odoo/addons/base/models/res_config.py b/odoo/addons/base/models/res_config.py index 7576568ddd6..71434304a35 100644 --- a/odoo/addons/base/models/res_config.py +++ b/odoo/addons/base/models/res_config.py @@ -413,14 +413,10 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin) return ret_val def onchange_module(self, field_value, module_name): - ModuleSudo = self.env['ir.module.module'].sudo() - modules = ModuleSudo.search( - [('name', '=', module_name.replace("module_", '')), - ('state', 'in', ['to install', 'installed', 'to upgrade'])]) - - if modules and not int(field_value): - deps = modules.sudo().downstream_dependencies() - dep_names = (deps | modules).mapped('shortdesc') + module_sudo = self.env['ir.module.module']._get(module_name[7:]) + if not int(field_value) and module_sudo.state in ('to install', 'installed', 'to upgrade'): + deps = module_sudo.downstream_dependencies() + dep_names = (deps | module_sudo).mapped('shortdesc') message = '\n'.join(dep_names) return { 'warning': { @@ -475,7 +471,7 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin) elif name.startswith('module_'): if field.type not in ('boolean', 'selection'): raise Exception("Field %s must have type 'boolean' or 'selection'" % field) - module = IrModule.sudo().search([('name', '=', name[7:])], limit=1) + module = IrModule._get(name[7:]) modules.append((name, module)) elif hasattr(field, 'config_parameter'): if field.type not in ('boolean', 'integer', 'float', 'char', 'selection', 'many2one', 'datetime'):