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