Code

Ticket #15849: 15849-ifchanged-not-thread-safe.2.diff

File 15849-ifchanged-not-thread-safe.2.diff, 1.6 KB (added by akaihola, 3 years ago)

Fixes #15849 -- use context.render_context instead of self for storing state in IfChangedNode. Also now use self instead of str(id(self)) as the key when storing the node in contextforloop?`. Patch is against r16046.

Line 
1diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
2index f4018ab..c5944a2 100644
3--- a/django/template/defaulttags.py
4+++ b/django/template/defaulttags.py
5@@ -240,14 +240,14 @@ class IfChangedNode(Node):
6 
7     def __init__(self, nodelist_true, nodelist_false, *varlist):
8         self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
9-        self._last_seen = None
10         self._varlist = varlist
11-        self._id = str(id(self))
12 
13     def render(self, context):
14-        if 'forloop' in context and self._id not in context['forloop']:
15-            self._last_seen = None
16-            context['forloop'][self._id] = 1
17+        if self not in context.render_context:
18+            context.render_context[self] = None  # last seen
19+        if 'forloop' in context and self not in context['forloop']:
20+            context.render_context[self] = None  # last seen
21+            context['forloop'][self] = 1
22         try:
23             if self._varlist:
24                 # Consider multiple parameters.  This automatically behaves
25@@ -258,9 +258,9 @@ class IfChangedNode(Node):
26         except VariableDoesNotExist:
27             compare_to = None
28 
29-        if compare_to != self._last_seen:
30-            firstloop = (self._last_seen == None)
31-            self._last_seen = compare_to
32+        if compare_to != context.render_context[self]:  # last seen
33+            firstloop = (context.render_context[self] == None)
34+            context.render_context[self] = compare_to
35             content = self.nodelist_true.render(context)
36             return content
37         elif self.nodelist_false: