Add 'where' operator to xxx2many
issue4507 review12951002
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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>``.
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
}])
|
||||
|
||||
Reference in New Issue
Block a user