You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
1.8 KiB
67 lines
1.8 KiB
""" |
|
Various data structures used in query construction. |
|
|
|
Factored out from django.db.models.query so that they can also be used by other |
|
modules without getting into circular import difficulties. |
|
""" |
|
|
|
from copy import deepcopy |
|
|
|
from django.utils import tree |
|
|
|
class QueryWrapper(object): |
|
""" |
|
A type that indicates the contents are an SQL fragment and the associate |
|
parameters. Can be used to pass opaque data to a where-clause, for example. |
|
""" |
|
def __init__(self, sql, params): |
|
self.data = sql, params |
|
|
|
class Q(tree.Node): |
|
""" |
|
Encapsulates filters as objects that can then be combined logically (using |
|
& and |). |
|
""" |
|
# Connection types |
|
AND = 'AND' |
|
OR = 'OR' |
|
default = AND |
|
|
|
def __init__(self, *args, **kwargs): |
|
super(Q, self).__init__(children=list(args) + kwargs.items()) |
|
|
|
def _combine(self, other, conn): |
|
if not isinstance(other, Q): |
|
raise TypeError(other) |
|
obj = deepcopy(self) |
|
obj.add(other, conn) |
|
return obj |
|
|
|
def __or__(self, other): |
|
return self._combine(other, self.OR) |
|
|
|
def __and__(self, other): |
|
return self._combine(other, self.AND) |
|
|
|
def __invert__(self): |
|
obj = deepcopy(self) |
|
obj.negate() |
|
return obj |
|
|
|
def select_related_descend(field, restricted, requested): |
|
""" |
|
Returns True if this field should be used to descend deeper for |
|
select_related() purposes. Used by both the query construction code |
|
(sql.query.fill_related_selections()) and the model instance creation code |
|
(query.get_cached_row()). |
|
""" |
|
if not field.rel: |
|
return False |
|
if field.rel.parent_link: |
|
return False |
|
if restricted and field.name not in requested: |
|
return False |
|
if not restricted and field.null: |
|
return False |
|
return True |
|
|
|
|