Skip to content

Commit

Permalink
Fix and optimize method 'filtered'
Browse files Browse the repository at this point in the history
  • Loading branch information
florentx committed Jan 1, 2019
1 parent 4e11f60 commit b5d4c97
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Changelog
* Provide cursor :attr:`Env.cr` in local mode, even with OpenERP
instances.

* Optimize and fix method :meth:`RecordList.filtered`.


2.1 (2018-12-27)
~~~~~~~~~~~~~~~~
Expand Down
21 changes: 10 additions & 11 deletions odooly.py
Original file line number Diff line number Diff line change
Expand Up @@ -1556,7 +1556,7 @@ def filtered(self, func):
ids = [rec._idnames[0] for rec in self if func(rec)]
return BaseRecord(self._model, ids)
recs = rels = self[:]
one2many = False # one2many or many2many
tomany = False
while func:
name, dot, func = func.partition('.')
tups = zip(recs, rels.read(name))
Expand All @@ -1565,21 +1565,20 @@ def filtered(self, func):
if not rel:
continue
if hasattr(rel, 'ids'):
if not rel.id:
if not rel.id: # record ID is False
continue
if func and len(rel.ids) > 1:
one2many = True
tomany = True
recs.append(rec)
rels.append(rel)
if not rels:
return self[:0]
if one2many:
recs = [rec for (rec, rel) in zip(recs, rels)
if rel.filtered(func)]
if not rels: # empty
break
if hasattr(rels[0], 'ids'):
rels = rels[0].concat(*rels[1:])
return recs[0].concat(*recs[1:])
if tomany: # one2many or many2many
frels, func = BaseRecord.union(*rels).filtered(func), ''
recs = [rec for (rec, rel) in zip(recs, rels) if rel & frels]
elif hasattr(rels[0], 'ids'):
rels = BaseRecord.concat(*rels)
return BaseRecord.concat(*recs) if recs else self[:0]

def sorted(self, key=None, reverse=False):
"""Return the records sorted by ``key``."""
Expand Down
8 changes: 2 additions & 6 deletions tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1134,7 +1134,7 @@ def test_mapped(self):

def test_filtered(self):
m = self.env['foo.bar']
items = [[k, 'Item %d' % k] for k in range(1, 21)]
items = [[k, 'Item %d' % k] for k in range(1, 9)]
self.service.object.execute_kw.side_effect = [
[{'id':k, 'flag1': not (k % 3)} for k in [4, 17, 7, 42, 112, 13]],
{'flag1': {'type': 'boolean'},
Expand All @@ -1148,8 +1148,6 @@ def test_filtered(self):
[{'id': 42, 'foo_child_ids': items[0:6]}, {'id': 17, 'foo_child_ids': items[6:8]}],
[{'id': k, 'flag3': (k < 3)} for k in range(1, 8)],
{'flag3': {'type': 'boolean'}},
[{'id': k, 'flag3': (k < 3)} for k in range(1, 8)],
[{'id': k, 'flag3': (k < 3)} for k in range(1, 8)],

[{'id': 42, 'foo_categ_id': False}],
[{'id': 88, 'foo_categ_id': [33, 'Categ 33']}],
Expand Down Expand Up @@ -1187,10 +1185,8 @@ def test_filtered(self):
OBJ('foo.categ', 'fields_get'),

OBJ('foo.bar', 'read', ids1_sorted, ['foo_child_ids']),
OBJ('foo.child', 'read', [1, 2, 3, 4, 5, 6], ['flag3']),
OBJ('foo.child', 'read', [1, 2, 3, 4, 5, 6, 7, 8], ['flag3']),
OBJ('foo.child', 'fields_get'),
OBJ('foo.child', 'read', [7, 8], ['flag3']),
OBJ('foo.child', 'read', [1, 2, 3, 4, 5, 6], ['flag3']),

OBJ('foo.bar', 'read', [42], ['foo_categ_id']),
OBJ('foo.bar', 'read', [88], ['foo_categ_id']),
Expand Down

0 comments on commit b5d4c97

Please sign in to comment.