Skip to content

Commit

Permalink
Properly merge field lookups (mvpdev/django-eav#43).
Browse files Browse the repository at this point in the history
  • Loading branch information
paxaxel223 committed Sep 4, 2017
1 parent 59ff77e commit 65c481e
Showing 1 changed file with 19 additions and 11 deletions.
30 changes: 19 additions & 11 deletions eav/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,37 +34,44 @@

def eav_filter(func):
'''
Decorator used to wrap filter and exlclude methods. Passes args through
Decorator used to wrap filter and exclude methods. Passes args through
expand_q_filters and kwargs through expand_eav_filter. Returns the
called function (filter or exclude)
'''

@wraps(func)
def wrapper(self, *args, **kwargs):
new_args = []
def wrapper(self, *args, **kwargs):
nargs = []
for arg in args:
if isinstance(arg, models.Q):
# modify Q objects (warning: recursion ahead)
# Modify Q objects (warning: recursion ahead).
arg = expand_q_filters(arg, self.model)
new_args.append(arg)
nargs.append(arg)

new_kwargs = {}
nkwargs = {}
for key, value in kwargs.items():
# modify kwargs (warning: recursion ahead)
new_key, new_value = expand_eav_filter(self.model, key, value)
new_kwargs.update({new_key: new_value})
# Modify kwargs (warning: recursion ahead).
nkey, nval = expand_eav_filter(self.model, key, value)

if nkey in nkwargs:
# Apply AND to both querysets.
nkwargs[nkey] = (nkwargs[nkey] & nval).distinct()
else:
nkwargs.update({nkey: nval})

return func(self, *new_args, **new_kwargs)
return func(self, *nargs, **nkwargs)

return wrapper


def expand_q_filters(q, root_cls):
'''
Takes a Q object and a model class.
Recursivley passes each filter / value in the Q object tree leaf nodes
through expand_eav_filter
'''
new_children = []

for qi in q.children:
if type(qi) is tuple:
# this child is a leaf node: in Q this is a 2-tuple of:
Expand All @@ -74,6 +81,7 @@ def expand_q_filters(q, root_cls):
else:
# this child is another Q node: recursify!
new_children.append(expand_q_filters(qi, root_cls))

q.children = new_children
return q

Expand Down

0 comments on commit 65c481e

Please sign in to comment.