changeset 84244f5b7641 in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset;node=84244f5b7641
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
diffstat:
trytond/model/tree.py | 56 ++++++++++++++++++++++--------------------
trytond/tests/test_tree.py | 60 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 27 deletions(-)
diffs (149 lines):
diff -r f6d3843711f6 -r 84244f5b7641 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 f6d3843711f6 -r 84244f5b7641 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()