[FIX] core: sorted of new records + prefetch
BaseModel's sorted() has two problems: - It breaks the prefetch of self for no reason - When it is called without an argument, it filters out new records because the search() used in sorted() doesn't return new records. Keep the same prefetch as self to fix the first problem. We partially fix/support the second issue, we just avoid filtering out new records (but we don't actually sort them) closes odoo/odoo#157145 X-original-commit: 0551c3b7e8e1469dabdb19d6420c544a1654fec5 Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
This commit is contained in:
@@ -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"},
|
||||
|
||||
+10
-5
@@ -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``. """
|
||||
|
||||
Reference in New Issue
Block a user