mirror of
https://github.com/Infinidat/infi.clickhouse_orm.git
synced 2024-11-26 02:33:45 +03:00
Add OR and AND operations for Q objects
This commit is contained in:
parent
ca8586b213
commit
0342dc863b
|
@ -143,9 +143,23 @@ class FOV(object):
|
||||||
|
|
||||||
class Q(object):
|
class Q(object):
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
AND_MODE = 'AND'
|
||||||
self._fovs = [self._build_fov(k, v) for k, v in six.iteritems(kwargs)]
|
OR_MODE = 'OR'
|
||||||
|
|
||||||
|
def __init__(self, **filter_fields):
|
||||||
|
self._fovs = [self._build_fov(k, v) for k, v in six.iteritems(filter_fields)]
|
||||||
|
self._l_child = None
|
||||||
|
self._r_child = None
|
||||||
self._negate = False
|
self._negate = False
|
||||||
|
self._mode = self.AND_MODE
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _construct_from(cls, l_child, r_child, mode):
|
||||||
|
q = Q()
|
||||||
|
q._l_child = l_child
|
||||||
|
q._r_child = r_child
|
||||||
|
q._mode = mode
|
||||||
|
return q
|
||||||
|
|
||||||
def _build_fov(self, key, value):
|
def _build_fov(self, key, value):
|
||||||
if '__' in key:
|
if '__' in key:
|
||||||
|
@ -155,13 +169,23 @@ class Q(object):
|
||||||
return FOV(field_name, operator, value)
|
return FOV(field_name, operator, value)
|
||||||
|
|
||||||
def to_sql(self, model_cls):
|
def to_sql(self, model_cls):
|
||||||
if not self._fovs:
|
if self._fovs:
|
||||||
|
sql = ' {} '.format(self._mode).join(fov.to_sql(model_cls) for fov in self._fovs)
|
||||||
|
else:
|
||||||
|
if self._l_child and self._r_child:
|
||||||
|
sql = '({}) {} ({})'.format(self._l_child.to_sql(model_cls), self._mode, self._r_child.to_sql(model_cls))
|
||||||
|
else:
|
||||||
return '1'
|
return '1'
|
||||||
sql = ' AND '.join(fov.to_sql(model_cls) for fov in self._fovs)
|
|
||||||
if self._negate:
|
if self._negate:
|
||||||
sql = 'NOT (%s)' % sql
|
sql = 'NOT (%s)' % sql
|
||||||
return sql
|
return sql
|
||||||
|
|
||||||
|
def __or__(self, other):
|
||||||
|
return Q._construct_from(self, other, self.OR_MODE)
|
||||||
|
|
||||||
|
def __and__(self, other):
|
||||||
|
return Q._construct_from(self, other, self.AND_MODE)
|
||||||
|
|
||||||
def __invert__(self):
|
def __invert__(self):
|
||||||
q = copy(self)
|
q = copy(self)
|
||||||
q._negate = True
|
q._negate = True
|
||||||
|
@ -286,20 +310,24 @@ class QuerySet(object):
|
||||||
qs._fields = field_names
|
qs._fields = field_names
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def filter(self, **kwargs):
|
def filter(self, *q, **filter_fields):
|
||||||
"""
|
"""
|
||||||
Returns a copy of this queryset that includes only rows matching the conditions.
|
Returns a copy of this queryset that includes only rows matching the conditions.
|
||||||
|
Add q object to query if it specified.
|
||||||
"""
|
"""
|
||||||
qs = copy(self)
|
qs = copy(self)
|
||||||
qs._q = list(self._q) + [Q(**kwargs)]
|
if q:
|
||||||
|
qs._q = list(self._q) + list(q)
|
||||||
|
else:
|
||||||
|
qs._q = list(self._q) + [Q(**filter_fields)]
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def exclude(self, **kwargs):
|
def exclude(self, **filter_fields):
|
||||||
"""
|
"""
|
||||||
Returns a copy of this queryset that excludes all rows matching the conditions.
|
Returns a copy of this queryset that excludes all rows matching the conditions.
|
||||||
"""
|
"""
|
||||||
qs = copy(self)
|
qs = copy(self)
|
||||||
qs._q = list(self._q) + [~Q(**kwargs)]
|
qs._q = list(self._q) + [~Q(**filter_fields)]
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
def paginate(self, page_num=1, page_size=100):
|
def paginate(self, page_num=1, page_size=100):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user