changeset a86dba790821 in trytond:5.6 details: https://hg.tryton.org/trytond?cmd=changeset;node=a86dba790821 description: Construct recursively Tree search_rec_name with 'in' operators
Each value of the 'in' operators must be processed as a '=' clause. The None values must be supported just in case it set in the 'in' values because the mixin does not allow empty name. issue9354 review304601002 (grafted from 84244f5b76418f093ce6212653ddd365259818ea) diffstat: trytond/model/tree.py | 56 ++++++++++++++++++++++-------------------- trytond/tests/test_tree.py | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 27 deletions(-) diffs (149 lines): diff -r b88a0fa56278 -r a86dba790821 trytond/model/tree.py --- a/trytond/model/tree.py Sat Oct 24 23:17:19 2020 +0200 +++ b/trytond/model/tree.py Mon Oct 26 21:27:13 2020 +0100 @@ -38,39 +38,41 @@ @classmethod def search_rec_name(cls, _, clause): + domain = [] if isinstance(clause[2], str): + field = name values = list(reversed(clause[2].split(separator))) + for value in values: + domain.append((field, clause[1], value.strip())) + field = parent + '.' + field + if (( + clause[1].endswith('like') + and not clause[2].replace( + '%%', '__').startswith('%')) + or not clause[1].endswith('like')): + if clause[1].startswith('not') or clause[1] == '!=': + operator = '!=' + domain.insert(0, 'OR') + else: + operator = '=' + top_parent = '.'.join((parent,) * len(values)) + domain.append((top_parent, operator, None)) + if (clause[1].endswith('like') + and clause[2].replace('%%', '__').endswith('%')): + ids = list(map(int, cls.search(domain, order=[]))) + domain = [(parent, 'child_of', ids)] + elif clause[2] is None: + domain.append((name, clause[1], clause[2])) else: - values = [[]] - for value in clause[2]: - if value is None: - values[0].append(value) - continue - for i, v in range(reversed(value.split(separator))): - while len(values) <= i: - values.append([]) - values[i].append(v) - domain = [] - field = name - for value in values: - domain.append((field, clause[1], value.strip())) - field = parent + '.' + field - if (( - clause[1].endswith('like') - and not clause[2].replace( - '%%', '__').startswith('%')) - or not clause[1].endswith('like')): - if clause[1].startswith('not') or clause[1] == '!=': + if clause[1].startswith('not'): operator = '!=' - domain.insert(0, 'OR') + domain.append('AND') else: operator = '=' - top_parent = '.'.join((parent,) * len(values)) - domain.append((top_parent, operator, None)) - if (clause[1].endswith('like') - and clause[2].replace('%%', '__').endswith('%')): - ids = list(map(int, cls.search(domain, order=[]))) - domain = [(parent, 'child_of', ids)] + domain.append('OR') + for value in clause[2]: + domain.append(cls.search_rec_name( + name, (clause[0], operator, value))) return domain @classmethod diff -r b88a0fa56278 -r a86dba790821 trytond/tests/test_tree.py --- a/trytond/tests/test_tree.py Sat Oct 24 23:17:19 2020 +0200 +++ b/trytond/tests/test_tree.py Mon Oct 26 21:27:13 2020 +0100 @@ -70,6 +70,21 @@ self.assertEqual(records, [parent]) @with_transaction() + def test_search_rec_name_equals_none(self): + "Test search_rec_name equals" + pool = Pool() + Tree = pool.get('test.tree') + + parent = Tree(name="parent") + parent.save() + record = Tree(name="record", parent=parent) + record.save() + + records = Tree.search([('rec_name', '=', None)]) + + self.assertEqual(records, []) + + @with_transaction() def test_search_rec_name_non_equals(self): "Test search_rec_name non equals" pool = Pool() @@ -100,6 +115,51 @@ self.assertEqual(records, [record]) @with_transaction() + def test_search_rec_name_non_equals_none(self): + "Test search_rec_name equals" + pool = Pool() + Tree = pool.get('test.tree') + + parent = Tree(name="parent") + parent.save() + record = Tree(name="record", parent=parent) + record.save() + + records = Tree.search([('rec_name', '!=', None)]) + + self.assertEqual(records, [parent, record]) + + @with_transaction() + def test_search_rec_name_in(self): + "Test search_rec_name in" + pool = Pool() + Tree = pool.get('test.tree') + + parent = Tree(name="parent") + parent.save() + record = Tree(name="record", parent=parent) + record.save() + + records = Tree.search([('rec_name', 'in', ['parent / record'])]) + + self.assertEqual(records, [record]) + + @with_transaction() + def test_search_rec_name_in_toplevel(self): + "Test search_rec_name in top-level" + pool = Pool() + Tree = pool.get('test.tree') + + parent = Tree(name="parent") + parent.save() + record = Tree(name="record", parent=parent) + record.save() + + records = Tree.search([('rec_name', 'in', ['parent'])]) + + self.assertEqual(records, [parent]) + + @with_transaction() def test_search_rec_name_like(self): "Test search_rec_name like" pool = Pool()