Skip to content

Commit 82a7277

Browse files
committed
Refs django-commons#910 - Thinking further on it. Using id() on the Context is probably not the wisest, as it is likely to mutate with pushes & pops during the course of renderings, which may add or remove keys which wouldn't be reflected in this re-use.
Doing the id() on the individual layers would work better, in this case, because pushes and pops don't mutate the underlying dict, just add new/remove existing ones.
1 parent 6154046 commit 82a7277

File tree

1 file changed

+19
-26
lines changed

1 file changed

+19
-26
lines changed

debug_toolbar/panels/templates/panel.py

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,18 @@ def _store_template_info(self, sender, **kwargs):
8484
template.name.startswith('debug_toolbar/')):
8585
return
8686

87-
# Refs #910
88-
# The same Context instance may be passed around a lot, so if we've
89-
# seen it before, just re-use the previous output.
90-
context_id = id(context)
91-
if context_id in self.seen_contexts:
92-
context_list = self.seen_contexts[context_id]
93-
else:
94-
context_list = []
95-
for context_layer in context.dicts:
96-
temp_layer = {}
97-
if hasattr(context_layer, 'items'):
87+
context_list = []
88+
for context_layer in context.dicts:
89+
if hasattr(context_layer, 'items'):
90+
# Refs #910
91+
# The same dictionary may be passed around a lot, so if we've
92+
# seen it before, just re-use the previous output.
93+
# We use the id *and* the keys because for some reason
94+
# just using the id doesn't work correctly (for example,
95+
# it misses a whole lot of data for select_option.html?)
96+
context_layer_id = (id(context_layer), tuple(sorted(context_layer.keys())))
97+
if context_layer_id not in self.seen_contexts:
98+
temp_layer = {}
9899
for key, value in context_layer.items():
99100
# Replace any request elements - they have a large
100101
# unicode representation and the request data is
@@ -128,21 +129,13 @@ def _store_template_info(self, sender, **kwargs):
128129
temp_layer[key] = value
129130
finally:
130131
recording(True)
131-
try:
132-
prettified_layer = force_text(pformat(temp_layer))
133-
except UnicodeEncodeError:
134-
pass
135-
else:
136-
context_list.append(prettified_layer)
137-
# Refs GitHub issue #910
138-
# After Django introduced template based form widget rendering,
139-
# djdt has to collect and format far more contexts, many of which
140-
# are duplicates, and don't need formatting if we've already seen
141-
# the exact same context.
142-
# At this point, we know this is the first time we've seen and
143-
# collected the layers of this context, so we store the value into
144-
# a dictionary whose key is the id() of the Context instance.
145-
self.seen_contexts[context_id] = context_list
132+
try:
133+
prettified_layer = force_text(pformat(temp_layer))
134+
except UnicodeEncodeError:
135+
pass
136+
else:
137+
self.seen_contexts[context_layer_id] = prettified_layer
138+
context_list.append(self.seen_contexts[context_layer_id])
146139

147140
kwargs['context'] = context_list
148141
kwargs['context_processors'] = getattr(context, 'context_processors', None)

0 commit comments

Comments
 (0)