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.

query_utils.py 13 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. """
  2. Various data structures used in query construction.
  3. Factored out from django.db.models.query to avoid making the main module very
  4. large and/or so that they can be used by other modules without getting into
  5. circular import difficulties.
  6. """
  7. from __future__ import unicode_literals
  8. import inspect
  9. from collections import namedtuple
  10. from django.core.exceptions import FieldDoesNotExist
  11. from django.db.backends import utils
  12. from django.db.models.constants import LOOKUP_SEP
  13. from django.utils import tree
  14. # PathInfo is used when converting lookups (fk__somecol). The contents
  15. # describe the relation in Model terms (model Options and Fields for both
  16. # sides of the relation. The join_field is the field backing the relation.
  17. PathInfo = namedtuple('PathInfo', 'from_opts to_opts target_fields join_field m2m direct')
  18. class InvalidQuery(Exception):
  19. """
  20. The query passed to raw isn't a safe query to use with raw.
  21. """
  22. pass
  23. class QueryWrapper(object):
  24. """
  25. A type that indicates the contents are an SQL fragment and the associate
  26. parameters. Can be used to pass opaque data to a where-clause, for example.
  27. """
  28. contains_aggregate = False
  29. def __init__(self, sql, params):
  30. self.data = sql, list(params)
  31. def as_sql(self, compiler=None, connection=None):
  32. return self.data
  33. class Q(tree.Node):
  34. """
  35. Encapsulates filters as objects that can then be combined logically (using
  36. `&` and `|`).
  37. """
  38. # Connection types
  39. AND = 'AND'
  40. OR = 'OR'
  41. default = AND
  42. def __init__(self, *args, **kwargs):
  43. super(Q, self).__init__(children=list(args) + list(kwargs.items()))
  44. def _combine(self, other, conn):
  45. if not isinstance(other, Q):
  46. raise TypeError(other)
  47. obj = type(self)()
  48. obj.connector = conn
  49. obj.add(self, conn)
  50. obj.add(other, conn)
  51. return obj
  52. def __or__(self, other):
  53. return self._combine(other, self.OR)
  54. def __and__(self, other):
  55. return self._combine(other, self.AND)
  56. def __invert__(self):
  57. obj = type(self)()
  58. obj.add(self, self.AND)
  59. obj.negate()
  60. return obj
  61. def clone(self):
  62. clone = self.__class__._new_instance(
  63. children=[], connector=self.connector, negated=self.negated)
  64. for child in self.children:
  65. if hasattr(child, 'clone'):
  66. clone.children.append(child.clone())
  67. else:
  68. clone.children.append(child)
  69. return clone
  70. def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
  71. # We must promote any new joins to left outer joins so that when Q is
  72. # used as an expression, rows aren't filtered due to joins.
  73. clause, joins = query._add_q(self, reuse, allow_joins=allow_joins, split_subq=False)
  74. query.promote_joins(joins)
  75. return clause
  76. @classmethod
  77. def _refs_aggregate(cls, obj, existing_aggregates):
  78. if not isinstance(obj, tree.Node):
  79. aggregate, aggregate_lookups = refs_aggregate(obj[0].split(LOOKUP_SEP), existing_aggregates)
  80. if not aggregate and hasattr(obj[1], 'refs_aggregate'):
  81. return obj[1].refs_aggregate(existing_aggregates)
  82. return aggregate, aggregate_lookups
  83. for c in obj.children:
  84. aggregate, aggregate_lookups = cls._refs_aggregate(c, existing_aggregates)
  85. if aggregate:
  86. return aggregate, aggregate_lookups
  87. return False, ()
  88. def refs_aggregate(self, existing_aggregates):
  89. if not existing_aggregates:
  90. return False
  91. return self._refs_aggregate(self, existing_aggregates)
  92. class DeferredAttribute(object):
  93. """
  94. A wrapper for a deferred-loading field. When the value is read from this
  95. object the first time, the query is executed.
  96. """
  97. def __init__(self, field_name, model):
  98. self.field_name = field_name
  99. def __get__(self, instance, owner):
  100. """
  101. Retrieves and caches the value from the datastore on the first lookup.
  102. Returns the cached value.
  103. """
  104. non_deferred_model = instance._meta.proxy_for_model
  105. opts = non_deferred_model._meta
  106. assert instance is not None
  107. data = instance.__dict__
  108. if data.get(self.field_name, self) is self:
  109. # self.field_name is the attname of the field, but only() takes the
  110. # actual name, so we need to translate it here.
  111. try:
  112. f = opts.get_field(self.field_name)
  113. except FieldDoesNotExist:
  114. f = [f for f in opts.fields if f.attname == self.field_name][0]
  115. name = f.name
  116. # Let's see if the field is part of the parent chain. If so we
  117. # might be able to reuse the already loaded value. Refs #18343.
  118. val = self._check_parent_chain(instance, name)
  119. if val is None:
  120. instance.refresh_from_db(fields=[self.field_name])
  121. val = getattr(instance, self.field_name)
  122. data[self.field_name] = val
  123. return data[self.field_name]
  124. def __set__(self, instance, value):
  125. """
  126. Deferred loading attributes can be set normally (which means there will
  127. never be a database lookup involved.
  128. """
  129. instance.__dict__[self.field_name] = value
  130. def _check_parent_chain(self, instance, name):
  131. """
  132. Check if the field value can be fetched from a parent field already
  133. loaded in the instance. This can be done if the to-be fetched
  134. field is a primary key field.
  135. """
  136. opts = instance._meta
  137. f = opts.get_field(name)
  138. link_field = opts.get_ancestor_link(f.model)
  139. if f.primary_key and f != link_field:
  140. return getattr(instance, link_field.attname)
  141. return None
  142. class RegisterLookupMixin(object):
  143. def _get_lookup(self, lookup_name):
  144. try:
  145. return self.class_lookups[lookup_name]
  146. except KeyError:
  147. # To allow for inheritance, check parent class' class_lookups.
  148. for parent in inspect.getmro(self.__class__):
  149. if 'class_lookups' not in parent.__dict__:
  150. continue
  151. if lookup_name in parent.class_lookups:
  152. return parent.class_lookups[lookup_name]
  153. except AttributeError:
  154. # This class didn't have any class_lookups
  155. pass
  156. return None
  157. def get_lookup(self, lookup_name):
  158. from django.db.models.lookups import Lookup
  159. found = self._get_lookup(lookup_name)
  160. if found is None and hasattr(self, 'output_field'):
  161. return self.output_field.get_lookup(lookup_name)
  162. if found is not None and not issubclass(found, Lookup):
  163. return None
  164. return found
  165. def get_transform(self, lookup_name):
  166. from django.db.models.lookups import Transform
  167. found = self._get_lookup(lookup_name)
  168. if found is None and hasattr(self, 'output_field'):
  169. return self.output_field.get_transform(lookup_name)
  170. if found is not None and not issubclass(found, Transform):
  171. return None
  172. return found
  173. @classmethod
  174. def register_lookup(cls, lookup, lookup_name=None):
  175. if lookup_name is None:
  176. lookup_name = lookup.lookup_name
  177. if 'class_lookups' not in cls.__dict__:
  178. cls.class_lookups = {}
  179. cls.class_lookups[lookup_name] = lookup
  180. return lookup
  181. @classmethod
  182. def _unregister_lookup(cls, lookup, lookup_name=None):
  183. """
  184. Remove given lookup from cls lookups. For use in tests only as it's
  185. not thread-safe.
  186. """
  187. if lookup_name is None:
  188. lookup_name = lookup.lookup_name
  189. del cls.class_lookups[lookup_name]
  190. def select_related_descend(field, restricted, requested, load_fields, reverse=False):
  191. """
  192. Returns True if this field should be used to descend deeper for
  193. select_related() purposes. Used by both the query construction code
  194. (sql.query.fill_related_selections()) and the model instance creation code
  195. (query.get_klass_info()).
  196. Arguments:
  197. * field - the field to be checked
  198. * restricted - a boolean field, indicating if the field list has been
  199. manually restricted using a requested clause)
  200. * requested - The select_related() dictionary.
  201. * load_fields - the set of fields to be loaded on this model
  202. * reverse - boolean, True if we are checking a reverse select related
  203. """
  204. if not field.remote_field:
  205. return False
  206. if field.remote_field.parent_link and not reverse:
  207. return False
  208. if restricted:
  209. if reverse and field.related_query_name() not in requested:
  210. return False
  211. if not reverse and field.name not in requested:
  212. return False
  213. if not restricted and field.null:
  214. return False
  215. if load_fields:
  216. if field.attname not in load_fields:
  217. if restricted and field.name in requested:
  218. raise InvalidQuery("Field %s.%s cannot be both deferred"
  219. " and traversed using select_related"
  220. " at the same time." %
  221. (field.model._meta.object_name, field.name))
  222. return False
  223. return True
  224. # This function is needed because data descriptors must be defined on a class
  225. # object, not an instance, to have any effect.
  226. def deferred_class_factory(model, attrs):
  227. """
  228. Returns a class object that is a copy of "model" with the specified "attrs"
  229. being replaced with DeferredAttribute objects. The "pk_value" ties the
  230. deferred attributes to a particular instance of the model.
  231. """
  232. if not attrs:
  233. return model
  234. opts = model._meta
  235. # Never create deferred models based on deferred model
  236. if model._deferred:
  237. # Deferred models are proxies for the non-deferred model. We never
  238. # create chains of defers => proxy_for_model is the non-deferred
  239. # model.
  240. model = opts.proxy_for_model
  241. # The app registry wants a unique name for each model, otherwise the new
  242. # class won't be created (we get an exception). Therefore, we generate
  243. # the name using the passed in attrs. It's OK to reuse an existing class
  244. # object if the attrs are identical.
  245. name = "%s_Deferred_%s" % (model.__name__, '_'.join(sorted(attrs)))
  246. name = utils.truncate_name(name, 80, 32)
  247. try:
  248. return opts.apps.get_model(model._meta.app_label, name)
  249. except LookupError:
  250. class Meta:
  251. proxy = True
  252. apps = opts.apps
  253. app_label = opts.app_label
  254. overrides = {attr: DeferredAttribute(attr, model) for attr in attrs}
  255. overrides["Meta"] = Meta
  256. overrides["__module__"] = model.__module__
  257. overrides["_deferred"] = True
  258. return type(str(name), (model,), overrides)
  259. # The above function is also used to unpickle model instances with deferred
  260. # fields.
  261. deferred_class_factory.__safe_for_unpickling__ = True
  262. def refs_aggregate(lookup_parts, aggregates):
  263. """
  264. A helper method to check if the lookup_parts contains references
  265. to the given aggregates set. Because the LOOKUP_SEP is contained in the
  266. default annotation names we must check each prefix of the lookup_parts
  267. for a match.
  268. """
  269. for n in range(len(lookup_parts) + 1):
  270. level_n_lookup = LOOKUP_SEP.join(lookup_parts[0:n])
  271. if level_n_lookup in aggregates and aggregates[level_n_lookup].contains_aggregate:
  272. return aggregates[level_n_lookup], lookup_parts[n:]
  273. return False, ()
  274. def refs_expression(lookup_parts, annotations):
  275. """
  276. A helper method to check if the lookup_parts contains references
  277. to the given annotations set. Because the LOOKUP_SEP is contained in the
  278. default annotation names we must check each prefix of the lookup_parts
  279. for a match.
  280. """
  281. for n in range(len(lookup_parts) + 1):
  282. level_n_lookup = LOOKUP_SEP.join(lookup_parts[0:n])
  283. if level_n_lookup in annotations and annotations[level_n_lookup]:
  284. return annotations[level_n_lookup], lookup_parts[n:]
  285. return False, ()
  286. def check_rel_lookup_compatibility(model, target_opts, field):
  287. """
  288. Check that self.model is compatible with target_opts. Compatibility
  289. is OK if:
  290. 1) model and opts match (where proxy inheritance is removed)
  291. 2) model is parent of opts' model or the other way around
  292. """
  293. def check(opts):
  294. return (
  295. model._meta.concrete_model == opts.concrete_model or
  296. opts.concrete_model in model._meta.get_parent_list() or
  297. model in opts.get_parent_list()
  298. )
  299. # If the field is a primary key, then doing a query against the field's
  300. # model is ok, too. Consider the case:
  301. # class Restaurant(models.Model):
  302. # place = OnetoOneField(Place, primary_key=True):
  303. # Restaurant.objects.filter(pk__in=Restaurant.objects.all()).
  304. # If we didn't have the primary key check, then pk__in (== place__in) would
  305. # give Place's opts as the target opts, but Restaurant isn't compatible
  306. # with that. This logic applies only to primary keys, as when doing __in=qs,
  307. # we are going to turn this into __in=qs.values('pk') later on.
  308. return (
  309. check(target_opts) or
  310. (getattr(field, 'primary_key', False) and check(field.model._meta))
  311. )