|
| 1 | +--- ../x/env/lib/python2.7/site-packages/django/db/models/query.py 2017-04-07 15:10:29.426831000 -0700 |
| 2 | ++++ env/lib/python2.7/site-packages/django/db/models/query.py 2017-04-07 15:18:39.938521412 -0700 |
| 3 | +@@ -5,6 +5,8 @@ |
| 4 | + import copy |
| 5 | + import sys |
| 6 | + import warnings |
| 7 | ++import inspect |
| 8 | ++import logging |
| 9 | + from collections import OrderedDict, deque |
| 10 | + |
| 11 | + from django.conf import settings |
| 12 | +@@ -34,6 +36,7 @@ |
| 13 | + # Pull into this namespace for backwards compatibility. |
| 14 | + EmptyResultSet = sql.EmptyResultSet |
| 15 | + |
| 16 | ++logger = logging.getLogger('django.db.backends') |
| 17 | + |
| 18 | + class BaseIterable(object): |
| 19 | + def __init__(self, queryset): |
| 20 | +@@ -51,6 +54,7 @@ |
| 21 | + compiler = queryset.query.get_compiler(using=db) |
| 22 | + # Execute the query. This will also fill compiler.select, klass_info, |
| 23 | + # and annotations. |
| 24 | ++ |
| 25 | + results = compiler.execute_sql() |
| 26 | + select, klass_info, annotation_col_map = (compiler.select, compiler.klass_info, |
| 27 | + compiler.annotation_col_map) |
| 28 | +@@ -174,6 +178,8 @@ |
| 29 | + self._known_related_objects = {} # {rel_field, {pk: rel_obj}} |
| 30 | + self._iterable_class = ModelIterable |
| 31 | + self._fields = None |
| 32 | ++ self._origin = [] |
| 33 | ++ self._djangodir = __file__[:(__file__.index('django')+len('django')+1)] |
| 34 | + |
| 35 | + def as_manager(cls): |
| 36 | + # Address the circular dependency between `Queryset` and `Manager`. |
| 37 | +@@ -316,6 +322,37 @@ |
| 38 | + combined.query.combine(other.query, sql.OR) |
| 39 | + return combined |
| 40 | + |
| 41 | ++ def _add_origin(self, depth=1): |
| 42 | ++ if settings.DEBUG: |
| 43 | ++ # get list of frame records. Each is: |
| 44 | ++ # [ frame, filename, lineno, function, code_context, index ] |
| 45 | ++ stack = inspect.stack() |
| 46 | ++ # caller stack record |
| 47 | ++ method = stack[depth][3] |
| 48 | ++ # look for the first stack entry which is not from django |
| 49 | ++ i = 0 |
| 50 | ++ while i<len(stack) and stack[i][1].startswith(self._djangodir) and not stack[i][3] == 'render': |
| 51 | ++ i += 1 |
| 52 | ++ if i<len(stack): |
| 53 | ++ stack = stack[i:] |
| 54 | ++ frame = stack[0][0] |
| 55 | ++ function = stack[0][3] |
| 56 | ++ if function == 'render' and 'context' in frame.f_locals: |
| 57 | ++ that = frame.f_locals['self'] |
| 58 | ++ if hasattr(that, 'filename'): |
| 59 | ++ import debug |
| 60 | ++ debug.show('that.filename') |
| 61 | ++ self._origin += [stack[0]+(method,), ] |
| 62 | ++ else: |
| 63 | ++ self._origin += [stack[2]+(method,), ] |
| 64 | ++ |
| 65 | ++ def _log_origin(self): |
| 66 | ++ if settings.DEBUG: |
| 67 | ++ self._add_origin(depth=3) |
| 68 | ++ for place in self._origin: |
| 69 | ++ frame, filename, lineno, function, code_context, index, method = place[:7] |
| 70 | ++ logger.debug("QuerySet: %s(%s) in %s: %s()\n %s", filename, lineno, function, method, code_context[index].rstrip()) |
| 71 | ++ |
| 72 | + #################################### |
| 73 | + # METHODS THAT DO DATABASE QUERIES # |
| 74 | + #################################### |
| 75 | +@@ -793,6 +830,7 @@ |
| 76 | + Returns a new QuerySet instance with the args ANDed to the existing |
| 77 | + set. |
| 78 | + """ |
| 79 | ++ self._add_origin() |
| 80 | + return self._filter_or_exclude(False, *args, **kwargs) |
| 81 | + |
| 82 | + def exclude(self, *args, **kwargs): |
| 83 | +@@ -800,6 +838,7 @@ |
| 84 | + Returns a new QuerySet instance with NOT (args) ANDed to the existing |
| 85 | + set. |
| 86 | + """ |
| 87 | ++ self._add_origin() |
| 88 | + return self._filter_or_exclude(True, *args, **kwargs) |
| 89 | + |
| 90 | + def _filter_or_exclude(self, negate, *args, **kwargs): |
| 91 | +@@ -824,6 +863,7 @@ |
| 92 | + This exists to support framework features such as 'limit_choices_to', |
| 93 | + and usually it will be more natural to use other methods. |
| 94 | + """ |
| 95 | ++ self._add_origin() |
| 96 | + if isinstance(filter_obj, Q) or hasattr(filter_obj, 'add_to_query'): |
| 97 | + clone = self._clone() |
| 98 | + clone.query.add_q(filter_obj) |
| 99 | +@@ -836,6 +876,7 @@ |
| 100 | + Returns a new QuerySet instance that will select objects with a |
| 101 | + FOR UPDATE lock. |
| 102 | + """ |
| 103 | ++ self._add_origin() |
| 104 | + obj = self._clone() |
| 105 | + obj._for_write = True |
| 106 | + obj.query.select_for_update = True |
| 107 | +@@ -855,6 +896,7 @@ |
| 108 | + if self._fields is not None: |
| 109 | + raise TypeError("Cannot call select_related() after .values() or .values_list()") |
| 110 | + |
| 111 | ++ self._add_origin() |
| 112 | + obj = self._clone() |
| 113 | + if fields == (None,): |
| 114 | + obj.query.select_related = False |
| 115 | +@@ -874,6 +916,7 @@ |
| 116 | + prefetch is appended to. If prefetch_related(None) is called, the list |
| 117 | + is cleared. |
| 118 | + """ |
| 119 | ++ self._add_origin() |
| 120 | + clone = self._clone() |
| 121 | + if lookups == (None,): |
| 122 | + clone._prefetch_related_lookups = [] |
| 123 | +@@ -886,6 +929,7 @@ |
| 124 | + Return a query set in which the returned objects have been annotated |
| 125 | + with extra data or aggregations. |
| 126 | + """ |
| 127 | ++ self._add_origin() |
| 128 | + annotations = OrderedDict() # To preserve ordering of args |
| 129 | + for arg in args: |
| 130 | + # The default_alias property may raise a TypeError, so we use |
| 131 | +@@ -929,6 +973,7 @@ |
| 132 | + """ |
| 133 | + assert self.query.can_filter(), \ |
| 134 | + "Cannot reorder a query once a slice has been taken." |
| 135 | ++ self._add_origin() |
| 136 | + obj = self._clone() |
| 137 | + obj.query.clear_ordering(force_empty=False) |
| 138 | + obj.query.add_ordering(*field_names) |
| 139 | +@@ -940,6 +985,7 @@ |
| 140 | + """ |
| 141 | + assert self.query.can_filter(), \ |
| 142 | + "Cannot create distinct fields once a slice has been taken." |
| 143 | ++ self._add_origin() |
| 144 | + obj = self._clone() |
| 145 | + obj.query.add_distinct_fields(*field_names) |
| 146 | + return obj |
| 147 | +@@ -951,6 +997,7 @@ |
| 148 | + """ |
| 149 | + assert self.query.can_filter(), \ |
| 150 | + "Cannot change a query once a slice has been taken" |
| 151 | ++ self._add_origin() |
| 152 | + clone = self._clone() |
| 153 | + clone.query.add_extra(select, select_params, where, params, tables, order_by) |
| 154 | + return clone |
| 155 | +@@ -959,6 +1006,7 @@ |
| 156 | + """ |
| 157 | + Reverses the ordering of the QuerySet. |
| 158 | + """ |
| 159 | ++ self._add_origin() |
| 160 | + clone = self._clone() |
| 161 | + clone.query.standard_ordering = not clone.query.standard_ordering |
| 162 | + return clone |
| 163 | +@@ -973,6 +1021,7 @@ |
| 164 | + """ |
| 165 | + if self._fields is not None: |
| 166 | + raise TypeError("Cannot call defer() after .values() or .values_list()") |
| 167 | ++ self._add_origin() |
| 168 | + clone = self._clone() |
| 169 | + if fields == (None,): |
| 170 | + clone.query.clear_deferred_loading() |
| 171 | +@@ -992,6 +1041,7 @@ |
| 172 | + # Can only pass None to defer(), not only(), as the rest option. |
| 173 | + # That won't stop people trying to do this, so let's be explicit. |
| 174 | + raise TypeError("Cannot pass None as an argument to only().") |
| 175 | ++ self._add_origin() |
| 176 | + clone = self._clone() |
| 177 | + clone.query.add_immediate_loading(fields) |
| 178 | + return clone |
| 179 | +@@ -1078,13 +1128,17 @@ |
| 180 | + clone._known_related_objects = self._known_related_objects |
| 181 | + clone._iterable_class = self._iterable_class |
| 182 | + clone._fields = self._fields |
| 183 | ++ clone._origin = self._origin |
| 184 | + |
| 185 | + clone.__dict__.update(kwargs) |
| 186 | + return clone |
| 187 | + |
| 188 | + def _fetch_all(self): |
| 189 | + if self._result_cache is None: |
| 190 | ++ self._log_origin() |
| 191 | + self._result_cache = list(self.iterator()) |
| 192 | ++ if settings.DEBUG: |
| 193 | ++ connections[self.db].queries_log[-1]['origin'] = self._origin |
| 194 | + if self._prefetch_related_lookups and not self._prefetch_done: |
| 195 | + self._prefetch_related_objects() |
| 196 | + |
0 commit comments