Skip to content

Commit

Permalink
Fix condition_filter with relationship
Browse files Browse the repository at this point in the history
  • Loading branch information
jssuzanne committed Feb 5, 2018
1 parent ba10c2c commit e836094
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 36 deletions.
3 changes: 2 additions & 1 deletion anyblok_pyramid/bloks/authorization/authorization.py
Expand Up @@ -28,7 +28,8 @@ class Authorization:
primary_keys = Json(default={})
filter = Json(default={})

role = String(foreign_key=User.Role.use('name').options(ondelete='cascade'))
role = Many2One(
model=User.Role, foreign_key_options={'ondelete': 'cascade'})
login = String(foreign_key=User.use('login').options(ondelete="cascade"))
user = Many2One(model=User)

Expand Down
70 changes: 38 additions & 32 deletions anyblok_pyramid/bloks/authorization/query.py
Expand Up @@ -12,24 +12,28 @@

def condition_filter(query, conditions, objects):
if 'or' in conditions:
compiled = sub_condition_filter(query, conditions['or'], objects)
return or_(*compiled)
query, compiled = sub_condition_filter(
query, conditions['or'], objects)
return query, or_(*compiled)
elif 'and' in conditions:
compiled = sub_condition_filter(query, conditions['and'], objects)
return and_(*compiled)
query, compiled = sub_condition_filter(
query, conditions['and'], objects)
return query, and_(*compiled)
elif 'not' in conditions:
compiled = sub_condition_filter(query, [conditions['not']], objects)
return ~ compiled[0]
query, compiled = sub_condition_filter(
query, [conditions['not']], objects)
return query, ~ compiled[0]

return condition_filter_leaf(query, conditions, objects)


def sub_condition_filter(query, conditions, objects):
compiled = []
compileds = []
for condition in conditions:
compiled.append(condition_filter(query, condition, objects))
query, compiled = condition_filter(query, condition, objects)
compileds.append(compiled)

return compiled
return query, compileds


def get_value_for(query, conditions, key_value, key_condition, key_adapter,
Expand All @@ -39,29 +43,31 @@ def get_value_for(query, conditions, key_value, key_condition, key_adapter,
if key_adapter in conditions:
value = adapt_value(conditions[key_adapter], value)

return value
return query, value

if key_condition in conditions:
value = conditions[key_condition].split('.')
entry = objects[value[0]]
keys = value[1:]
if len(keys) > 1:
return get_value_for_relationship(query, entry, keys)
return query, get_value_for_relationship(query, entry, keys)

return getattr(entry, keys[0])
return query, getattr(entry, keys[0])

return query, None


def get_value_for_relationship(query, entry, keys):
res = getattr(entry, keys[0], None)
if len(keys) == 1:
return res
return query, res

if hasattr(entry, '__registry_name__'):
Model = query.registry.get(entry.__registry_name__)
if entry is Model:
query.join(res)
query = query.join(res)

return get_value_for_relationship(query, res, keys[1:])
return query, get_value_for_relationship(query, res, keys[1:])


def adapt_value(adapter, value):
Expand All @@ -70,48 +76,48 @@ def adapt_value(adapter, value):


def condition_filter_leaf(query, conditions, objects): # noqa
left = get_value_for(
query, left = get_value_for(
query, conditions, 'left_value', 'left_condition', 'left_adapter',
objects)
right = get_value_for(
query, right = get_value_for(
query, conditions, 'right_value', 'right_condition', 'right_adapter',
objects)
operator = conditions.get('operator')

if operator == '==':
return left == right
return query, left == right
if operator == '!=':
return left != right
return query, left != right
if operator == 'in':
return left.in_(right)
return query, left.in_(right)
if operator == 'not in':
return left.notin(right)
return query, left.notin(right)
if operator == '<':
return left < right
return query, left < right
if operator == '<=':
return left <= right
return query, left <= right
if operator == '>':
return left > right
return query, left > right
if operator == '>=':
return left >= right
return query, left >= right
if operator == 'like':
return left.like(right)
return query, left.like(right)
if operator == 'not like':
return ~ left.like(right)
return query, ~ left.like(right)
if operator == 'ilike':
return left.ilike(right)
return query, left.ilike(right)
if operator == 'not ilike':
return ~ left.ilike(right)
return query, ~ left.ilike(right)

return None
return query, None


@Declarations.register(Declarations.Core)
class Query:

def condition_filter(self, conditions, objects):
compiled = condition_filter(self, conditions, objects)
query, compiled = condition_filter(self, conditions, objects)
if compiled is None:
return self

return self.filter(compiled)
return query.filter(compiled)
20 changes: 20 additions & 0 deletions anyblok_pyramid/bloks/authorization/tests/test_query.py
Expand Up @@ -244,3 +244,23 @@ def test_in_condition(self):
}
)
self.assertEqual(query.count(), 2)

def test_with_relationship(self):
user = self.registry.User.insert(login="jssuzanne", first_name="js",
last_name="suzanne")
role = self.registry.User.Role.insert(name='admin', label="Admin")
role.users.append(user)
authorization = self.registry.User.Authorization.insert(
resource='test', role=role)
query = self.registry.User.Authorization.query().condition_filter(
dict(
left_condition='Authorization.role.users.name',
operator='=',
right_value='jssuzanne',
),
{
'Authorization': self.registry.User.Authorization
}
)
self.assertEqual(query.count(), 1)
self.assertIs(query.one(), authorization)
6 changes: 3 additions & 3 deletions anyblok_pyramid/bloks/authorization/tests/test_validation.py
Expand Up @@ -16,17 +16,17 @@ def setUp(self):
self.user = self.registry.User.insert(
login='jssuzanne', first_name='Jean-Sébastien',
last_name='Suzanne')
role = self.registry.User.Role.insert(
self.role = self.registry.User.Role.insert(
name='admin', label='Administrator')
role.users.append(self.user)
self.role.users.append(self.user)

def get_entry_value(self):
return dict(
resource='Model.System.Blok',
model='Model.System.Blok',
primary_keys={'name': 'authorization'},
filter={'state': 'installed'},
role='admin',
role=self.role,
login='jssuzanne',
)

Expand Down

0 comments on commit e836094

Please sign in to comment.