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.
 
 
 
 

364 lines
13 KiB

  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. )