diff --git a/odoo/addons/base/tests/test_expression.py b/odoo/addons/base/tests/test_expression.py index 067674c0648..9682783a89f 100644 --- a/odoo/addons/base/tests/test_expression.py +++ b/odoo/addons/base/tests/test_expression.py @@ -1228,12 +1228,8 @@ class TestQueries(TransactionCase): # search on both 'name' and 'model' self.assertEqual(Model._rec_names_search, ['name', 'model']) - # warmup - Model.name_search('foo') - - Model.name_search('partner') with self.assertQueries([''' - SELECT "ir_model"."id" + SELECT "ir_model"."id", "ir_model"."name"->>'en_US' FROM "ir_model" WHERE ( ("ir_model"."name"->>'en_US' ILIKE %s) @@ -1244,9 +1240,8 @@ class TestQueries(TransactionCase): ''']): Model.name_search('foo') - Model.name_search('partner', operator='not ilike') with self.assertQueries([''' - SELECT "ir_model"."id" + SELECT "ir_model"."id", "ir_model"."name"->>'en_US' FROM "ir_model" WHERE ( ("ir_model"."name" is NULL OR "ir_model"."name"->>'en_US' not ilike %s) diff --git a/odoo/addons/test_performance/tests/test_performance.py b/odoo/addons/test_performance/tests/test_performance.py index f15ff2bb85b..4129cd2dfd6 100644 --- a/odoo/addons/test_performance/tests/test_performance.py +++ b/odoo/addons/test_performance/tests/test_performance.py @@ -216,6 +216,17 @@ class TestPerformance(SavepointCaseWithUserDemo): expected, ) + @warmup + def test_name_search(self): + """ Test that `name` is fetch in the same query than the search + to compute `display_name` without any additional query """ + Model = self.env['test_performance.base'] + record = Model.create({'name': 'blablu'}) + record.invalidate_recordset() + + with self.assertQueryCount(1): + Model.name_search('blablu') + @users('__system__', 'demo') @warmup def test_write_base(self): diff --git a/odoo/models.py b/odoo/models.py index 71b30d62e92..fd6a6d32d2b 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -1685,7 +1685,15 @@ class BaseModel(metaclass=MetaModel): :return: list of pairs ``(id, text_repr)`` for all matching records. """ ids = self._name_search(name, args, operator, limit=limit, order=self._order) - return [(record.id, record.display_name) for record in self.browse(ids).sudo()] + + if isinstance(ids, Query): + records = self._fetch_query(ids, self._determine_fields_to_fetch(['display_name'])) + else: + # Some override of `_name_search` return list of ids. + records = self.browse(ids) + records.fetch(['display_name']) + + return [(record.id, record.display_name) for record in records.sudo()] @api.model def _name_search(self, name, domain=None, operator='ilike', limit=None, order=None):