mirror of
https://github.com/jazzband/django-eav2.git
synced 2026-05-15 02:55:05 +00:00
added Q filtering magic to the eav manager. Recursively rebuilds the Q tree in-place before passing to the super class' filter.
This commit is contained in:
parent
9ae619a225
commit
cda3bbab2b
1 changed files with 30 additions and 1 deletions
31
managers.py
31
managers.py
|
|
@ -1,4 +1,5 @@
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models import Q
|
||||||
#from django.db.models import Aggregate
|
#from django.db.models import Aggregate
|
||||||
from .models import EavAttribute
|
from .models import EavAttribute
|
||||||
|
|
||||||
|
|
@ -63,10 +64,38 @@ def expand_filter_string(q_str, root_cls):
|
||||||
# query work, for passing up to the super call to filter()
|
# query work, for passing up to the super call to filter()
|
||||||
return '__'.join(filter_tokens), extra_filters
|
return '__'.join(filter_tokens), extra_filters
|
||||||
|
|
||||||
|
def expand_q_filters(q, root_cls):
|
||||||
|
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:
|
||||||
|
# (filter parameter, value)
|
||||||
|
expanded_string, extra_filters = expand_filter_string(qi[0], root_cls)
|
||||||
|
extra_filters.update({expanded_string: qi[1]})
|
||||||
|
if q.connector == 'OR':
|
||||||
|
# if it's an or, we now have additional filters that need
|
||||||
|
# to be ANDed together, so we have to make a sub-Q child
|
||||||
|
# in place of the original tuple
|
||||||
|
new_children.append(Q(**extra_filters))
|
||||||
|
else:
|
||||||
|
# otherwise, we can just append all the new filters, they're
|
||||||
|
# ANDed together anyway
|
||||||
|
for k,v in extra_filters.items():
|
||||||
|
new_children.append((k,v))
|
||||||
|
else:
|
||||||
|
# this child is another Q node: recursify!
|
||||||
|
new_children.append(expand_q_filters(qi, root_cls))
|
||||||
|
q.children = new_children
|
||||||
|
return q
|
||||||
|
|
||||||
class EntityManager(models.Manager):
|
class EntityManager(models.Manager):
|
||||||
def filter(self, *args, **kwargs):
|
def filter(self, *args, **kwargs):
|
||||||
qs = self.get_query_set().filter(*args)
|
|
||||||
cls = self.model
|
cls = self.model
|
||||||
|
for arg in args:
|
||||||
|
if isinstance(arg, Q):
|
||||||
|
# modify Q objects in-place (warning: recursion ahead)
|
||||||
|
expand_q_filters(arg, cls)
|
||||||
|
qs = self.get_query_set().filter(*args)
|
||||||
for lookup, value in kwargs.items():
|
for lookup, value in kwargs.items():
|
||||||
updated_lookup, extra_filters = expand_filter_string(lookup, cls)
|
updated_lookup, extra_filters = expand_filter_string(lookup, cls)
|
||||||
extra_filters.update({updated_lookup: value})
|
extra_filters.update({updated_lookup: value})
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue