diff --git a/odoo/addons/base/tests/test_api.py b/odoo/addons/base/tests/test_api.py index 8b2c81171f8..7a018fa1de4 100644 --- a/odoo/addons/base/tests/test_api.py +++ b/odoo/addons/base/tests/test_api.py @@ -670,6 +670,38 @@ class TestAPI(SavepointCaseWithUserDemo): by_name_ids = [p.id for p in sorted(ps, key=lambda p: p.name, reverse=True)] self.assertEqual(ps.sorted('name', reverse=True).ids, by_name_ids) + # sorted doesn't filter out new records but don't sort them either (limitation) + new_p = self.env['res.partner'].new({ + 'child_ids': [ + Command.create({'name': 'z'}), + Command.create({'name': 'a'}), + ], + }) + self.assertEqual(len(new_p.child_ids.sorted()), 2) + + # sorted keeps the _prefetch_ids + partners_with_children = self.env['res.partner'].create([ + { + 'name': 'required', + 'child_ids': [ + Command.create({'name': 'z'}), + Command.create({'name': 'a'}), + ], + }, + { + 'name': 'required', + 'child_ids': [ + Command.create({'name': 'z'}), + Command.create({'name': 'a'}), + ], + }, + ]) + partners_with_children.invalidate_model(['name']) + # Only one query to fetch name of children of each partner + with self.assertQueryCount(1): + for partner in partners_with_children: + partner.child_ids.sorted('id').mapped('name') + def test_group_on(self): p0, p1, p2 = self.env['res.partner'].create([ {'name': "bob", 'function': "guest"}, diff --git a/odoo/models.py b/odoo/models.py index 986ad27a86f..5ce03fa100c 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -6268,11 +6268,16 @@ class BaseModel(metaclass=MetaModel): records.sorted(key=lambda r: r.name) """ if key is None: - recs = self.search([('id', 'in', self.ids)]) - return self.browse(reversed(recs._ids)) if reverse else recs - if isinstance(key, str): - key = itemgetter(key) - return self.browse(item.id for item in sorted(self, key=key, reverse=reverse)) + if any(self._ids): + ids = self.search([('id', 'in', self.ids)])._ids + else: # Don't support new ids because search() doesn't work on new records + ids = self._ids + ids = tuple(reversed(ids)) if reverse else ids + else: + if isinstance(key, str): + key = itemgetter(key) + ids = tuple(item.id for item in sorted(self, key=key, reverse=reverse)) + return self.__class__(self.env, ids, self._prefetch_ids) def update(self, values): """ Update the records in ``self`` with ``values``. """