197 lines
7.4 KiB
Diff
197 lines
7.4 KiB
Diff
--- ../x/env/lib/python2.7/site-packages/django/db/models/query.py 2017-04-07 15:10:29.426831000 -0700
|
|
+++ env/lib/python2.7/site-packages/django/db/models/query.py 2017-04-07 15:18:39.938521412 -0700
|
|
@@ -5,6 +5,8 @@
|
|
import copy
|
|
import sys
|
|
import warnings
|
|
+import inspect
|
|
+import logging
|
|
from collections import OrderedDict, deque
|
|
|
|
from django.conf import settings
|
|
@@ -34,6 +36,7 @@
|
|
# Pull into this namespace for backwards compatibility.
|
|
EmptyResultSet = sql.EmptyResultSet
|
|
|
|
+logger = logging.getLogger('django.db.backends')
|
|
|
|
class BaseIterable(object):
|
|
def __init__(self, queryset):
|
|
@@ -51,6 +54,7 @@
|
|
compiler = queryset.query.get_compiler(using=db)
|
|
# Execute the query. This will also fill compiler.select, klass_info,
|
|
# and annotations.
|
|
+
|
|
results = compiler.execute_sql()
|
|
select, klass_info, annotation_col_map = (compiler.select, compiler.klass_info,
|
|
compiler.annotation_col_map)
|
|
@@ -174,6 +178,8 @@
|
|
self._known_related_objects = {} # {rel_field, {pk: rel_obj}}
|
|
self._iterable_class = ModelIterable
|
|
self._fields = None
|
|
+ self._origin = []
|
|
+ self._djangodir = __file__[:(__file__.index('django')+len('django')+1)]
|
|
|
|
def as_manager(cls):
|
|
# Address the circular dependency between `Queryset` and `Manager`.
|
|
@@ -316,6 +322,37 @@
|
|
combined.query.combine(other.query, sql.OR)
|
|
return combined
|
|
|
|
+ def _add_origin(self, depth=1):
|
|
+ if settings.DEBUG:
|
|
+ # get list of frame records. Each is:
|
|
+ # [ frame, filename, lineno, function, code_context, index ]
|
|
+ stack = inspect.stack()
|
|
+ # caller stack record
|
|
+ method = stack[depth][3]
|
|
+ # look for the first stack entry which is not from django
|
|
+ i = 0
|
|
+ while i<len(stack) and stack[i][1].startswith(self._djangodir) and not stack[i][3] == 'render':
|
|
+ i += 1
|
|
+ if i<len(stack):
|
|
+ stack = stack[i:]
|
|
+ frame = stack[0][0]
|
|
+ function = stack[0][3]
|
|
+ if function == 'render' and 'context' in frame.f_locals:
|
|
+ that = frame.f_locals['self']
|
|
+ if hasattr(that, 'filename'):
|
|
+ import debug
|
|
+ debug.show('that.filename')
|
|
+ self._origin += [stack[0]+(method,), ]
|
|
+ else:
|
|
+ self._origin += [stack[2]+(method,), ]
|
|
+
|
|
+ def _log_origin(self):
|
|
+ if settings.DEBUG:
|
|
+ self._add_origin(depth=3)
|
|
+ for place in self._origin:
|
|
+ frame, filename, lineno, function, code_context, index, method = place[:7]
|
|
+ logger.debug("QuerySet: %s(%s) in %s: %s()\n %s", filename, lineno, function, method, code_context[index].rstrip())
|
|
+
|
|
####################################
|
|
# METHODS THAT DO DATABASE QUERIES #
|
|
####################################
|
|
@@ -793,6 +830,7 @@
|
|
Returns a new QuerySet instance with the args ANDed to the existing
|
|
set.
|
|
"""
|
|
+ self._add_origin()
|
|
return self._filter_or_exclude(False, *args, **kwargs)
|
|
|
|
def exclude(self, *args, **kwargs):
|
|
@@ -800,6 +838,7 @@
|
|
Returns a new QuerySet instance with NOT (args) ANDed to the existing
|
|
set.
|
|
"""
|
|
+ self._add_origin()
|
|
return self._filter_or_exclude(True, *args, **kwargs)
|
|
|
|
def _filter_or_exclude(self, negate, *args, **kwargs):
|
|
@@ -824,6 +863,7 @@
|
|
This exists to support framework features such as 'limit_choices_to',
|
|
and usually it will be more natural to use other methods.
|
|
"""
|
|
+ self._add_origin()
|
|
if isinstance(filter_obj, Q) or hasattr(filter_obj, 'add_to_query'):
|
|
clone = self._clone()
|
|
clone.query.add_q(filter_obj)
|
|
@@ -836,6 +876,7 @@
|
|
Returns a new QuerySet instance that will select objects with a
|
|
FOR UPDATE lock.
|
|
"""
|
|
+ self._add_origin()
|
|
obj = self._clone()
|
|
obj._for_write = True
|
|
obj.query.select_for_update = True
|
|
@@ -855,6 +896,7 @@
|
|
if self._fields is not None:
|
|
raise TypeError("Cannot call select_related() after .values() or .values_list()")
|
|
|
|
+ self._add_origin()
|
|
obj = self._clone()
|
|
if fields == (None,):
|
|
obj.query.select_related = False
|
|
@@ -874,6 +916,7 @@
|
|
prefetch is appended to. If prefetch_related(None) is called, the list
|
|
is cleared.
|
|
"""
|
|
+ self._add_origin()
|
|
clone = self._clone()
|
|
if lookups == (None,):
|
|
clone._prefetch_related_lookups = []
|
|
@@ -886,6 +929,7 @@
|
|
Return a query set in which the returned objects have been annotated
|
|
with extra data or aggregations.
|
|
"""
|
|
+ self._add_origin()
|
|
annotations = OrderedDict() # To preserve ordering of args
|
|
for arg in args:
|
|
# The default_alias property may raise a TypeError, so we use
|
|
@@ -929,6 +973,7 @@
|
|
"""
|
|
assert self.query.can_filter(), \
|
|
"Cannot reorder a query once a slice has been taken."
|
|
+ self._add_origin()
|
|
obj = self._clone()
|
|
obj.query.clear_ordering(force_empty=False)
|
|
obj.query.add_ordering(*field_names)
|
|
@@ -940,6 +985,7 @@
|
|
"""
|
|
assert self.query.can_filter(), \
|
|
"Cannot create distinct fields once a slice has been taken."
|
|
+ self._add_origin()
|
|
obj = self._clone()
|
|
obj.query.add_distinct_fields(*field_names)
|
|
return obj
|
|
@@ -951,6 +997,7 @@
|
|
"""
|
|
assert self.query.can_filter(), \
|
|
"Cannot change a query once a slice has been taken"
|
|
+ self._add_origin()
|
|
clone = self._clone()
|
|
clone.query.add_extra(select, select_params, where, params, tables, order_by)
|
|
return clone
|
|
@@ -959,6 +1006,7 @@
|
|
"""
|
|
Reverses the ordering of the QuerySet.
|
|
"""
|
|
+ self._add_origin()
|
|
clone = self._clone()
|
|
clone.query.standard_ordering = not clone.query.standard_ordering
|
|
return clone
|
|
@@ -973,6 +1021,7 @@
|
|
"""
|
|
if self._fields is not None:
|
|
raise TypeError("Cannot call defer() after .values() or .values_list()")
|
|
+ self._add_origin()
|
|
clone = self._clone()
|
|
if fields == (None,):
|
|
clone.query.clear_deferred_loading()
|
|
@@ -992,6 +1041,7 @@
|
|
# Can only pass None to defer(), not only(), as the rest option.
|
|
# That won't stop people trying to do this, so let's be explicit.
|
|
raise TypeError("Cannot pass None as an argument to only().")
|
|
+ self._add_origin()
|
|
clone = self._clone()
|
|
clone.query.add_immediate_loading(fields)
|
|
return clone
|
|
@@ -1078,13 +1128,17 @@
|
|
clone._known_related_objects = self._known_related_objects
|
|
clone._iterable_class = self._iterable_class
|
|
clone._fields = self._fields
|
|
+ clone._origin = self._origin
|
|
|
|
clone.__dict__.update(kwargs)
|
|
return clone
|
|
|
|
def _fetch_all(self):
|
|
if self._result_cache is None:
|
|
+ self._log_origin()
|
|
self._result_cache = list(self.iterator())
|
|
+ if settings.DEBUG:
|
|
+ connections[self.db].queries_log[-1]['origin'] = self._origin
|
|
if self._prefetch_related_lookups and not self._prefetch_done:
|
|
self._prefetch_related_objects()
|
|
|