Add 'where' operator to xxx2many

issue4507
review12951002
This commit is contained in:
Nicolas Évrard
2016-01-21 10:48:32 +01:00
parent fa0774cd1e
commit d4e3b605ef
6 changed files with 65 additions and 8 deletions
+1
View File
@@ -1,3 +1,4 @@
* Add 'where' operator for xxx2many fields
* Strip and unquote double-quote from Postgresql schema in search_path
* Move webdav into a separate module
* Don't read historized user when evaluating record rules as it could lead to
+16
View File
@@ -238,3 +238,19 @@ pattern, unless otherwise noted::
Is a parent child comparison operator. it is the negation of this
`parent_of`_ operator.
``ẁhere``
---------
Is a :class:`trytond.model.fields.One2Many` /
:class:`trytond.model.fields.Many2Many` domain operator. It returns true
for every row of the target model that match the domain specified as
``<operand>``.
``not where``
-------------
Is a :class:`trytond.model.fields.One2Many` /
:class:`trytond.model.fields.Many2Many` domain operator. It returns true
for every row of the target model that does not match the domain specified
as ``<operand>``.
+2
View File
@@ -1,6 +1,8 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
OPERATORS = (
'where',
'not where',
'child_of',
'not child_of',
'parent_of',
+18 -6
View File
@@ -286,6 +286,7 @@ class Many2Many(Field):
transaction = Transaction()
table, _ = tables[None]
name, operator, value = domain[:3]
assert operator not in {'where', 'not where'} or '.' not in name
if Relation._history and transaction.context.get('_datetime'):
relation = Relation.__table_history__()
@@ -361,11 +362,18 @@ class Many2Many(Field):
else:
_, target_name = name.split('.', 1)
relation_domain = [('%s.%s' % (self.target, target_name),)
+ tuple(domain[1:])]
if origin_field._type == 'reference':
relation_domain.append(
(self.origin, 'like', Model.__name__ + ',%'))
if operator not in {'where', 'not where'}:
relation_domain = [('%s.%s' % (self.target, target_name),)
+ tuple(domain[1:])]
if origin_field._type == 'reference':
relation_domain.append(
(self.origin, 'like', Model.__name__ + ',%'))
else:
relation_domain = []
for clause in value:
relation_domain.append(
('%s.%s' % (self.target, clause[0]),)
+ tuple(clause[1:]))
rule_domain = Rule.domain_get(Relation.__name__, mode='read')
if rule_domain:
relation_domain = [relation_domain, rule_domain]
@@ -376,4 +384,8 @@ class Many2Many(Field):
relation_domain, tables=relation_tables)
query_table = convert_from(None, relation_tables)
query = query_table.select(origin, where=expression)
return table.id.in_(query)
expression = table.id.in_(query)
if operator == 'not where':
expression = ~expression
return expression
+10 -2
View File
@@ -231,6 +231,7 @@ class One2Many(Field):
transaction = Transaction()
table, _ = tables[None]
name, operator, value = domain[:3]
assert operator not in {'where', 'not where'} or '.' not in name
if Target._history and transaction.context.get('_datetime'):
target = Target.__table_history__()
@@ -268,7 +269,10 @@ class One2Many(Field):
target_name = 'id'
else:
_, target_name = name.split('.', 1)
target_domain = [(target_name,) + tuple(domain[1:])]
if operator not in {'where', 'not where'}:
target_domain = [(target_name,) + tuple(domain[1:])]
else:
target_domain = value
if origin_field._type == 'reference':
target_domain.append(
(self.field, 'like', Model.__name__ + ',%'))
@@ -282,4 +286,8 @@ class One2Many(Field):
target_domain, tables=target_tables)
query_table = convert_from(None, target_tables)
query = query_table.select(origin, where=expression)
return table.id.in_(query)
expression = table.id.in_(query)
if operator == 'not where':
expression = ~expression
return expression
+18
View File
@@ -2363,6 +2363,15 @@ class FieldsTestCase(unittest.TestCase):
])
self.assertEqual(one2manys, [])
one2manys = one2many.search([
('targets', 'where', [('name', '=', 'target1')]),
])
self.assertEqual(one2manys, [one2many1])
one2manys = one2many.search([
('targets', 'not where', [('name', '=', 'target1')]),
])
self.assertEqual(one2manys, [])
one2many2, = one2many.create([{
'name': 'origin2',
}])
@@ -2557,6 +2566,15 @@ class FieldsTestCase(unittest.TestCase):
])
self.assertEqual(many2manys, [])
many2manys = many2many.search([
('targets', 'where', [('name', '=', 'target1')]),
])
self.assertEqual(many2manys, [many2many1])
many2manys = many2many.search([
('targets', 'not where', [('name', '=', 'target1')]),
])
self.assertEqual(many2manys, [])
many2many2, = many2many.create([{
'name': 'origin2',
}])