Code

Ticket #14365: 14365_r13962.diff

File 14365_r13962.diff, 6.1 KB (added by carljm, 4 years ago)
Line 
1diff --git a/django/template/__init__.py b/django/template/__init__.py
2index c316786..60cbc03 100644
3--- a/django/template/__init__.py
4+++ b/django/template/__init__.py
5@@ -54,6 +54,7 @@ from inspect import getargspec
6 
7 from django.conf import settings
8 from django.template.context import Context, RequestContext, ContextPopException
9+from django.template.signals import template_rendered
10 from django.utils.importlib import import_module
11 from django.utils.itercompat import is_iterable
12 from django.utils.functional import curry, Promise
13@@ -148,6 +149,8 @@ class StringOrigin(Origin):
14         return self.source
15 
16 class Template(object):
17+    send_rendered_signal = settings.TEMPLATE_DEBUG
18+
19     def __init__(self, template_string, origin=None, name='<Unknown Template>'):
20         try:
21             template_string = smart_unicode(template_string)
22@@ -164,6 +167,8 @@ class Template(object):
23                 yield subnode
24 
25     def _render(self, context):
26+        if self.send_rendered_signal:
27+            template_rendered.send(sender=self, template=self, context=context)
28         return self.nodelist.render(context)
29 
30     def render(self, context):
31diff --git a/django/template/signals.py b/django/template/signals.py
32new file mode 100644
33index 0000000..a328a77
34--- /dev/null
35+++ b/django/template/signals.py
36@@ -0,0 +1,3 @@
37+from django.dispatch import Signal
38+
39+template_rendered = Signal(providing_args=["template", "context"])
40diff --git a/django/test/client.py b/django/test/client.py
41index 08e3ff6..3251275 100644
42--- a/django/test/client.py
43+++ b/django/test/client.py
44@@ -16,7 +16,7 @@ from django.core.handlers.wsgi import WSGIRequest
45 from django.core.signals import got_request_exception
46 from django.http import SimpleCookie, HttpRequest, QueryDict
47 from django.template import TemplateDoesNotExist
48-from django.test import signals
49+from django.template import signals
50 from django.utils.functional import curry
51 from django.utils.encoding import smart_str
52 from django.utils.http import urlencode
53diff --git a/django/test/signals.py b/django/test/signals.py
54deleted file mode 100644
55index a328a77..0000000
56--- a/django/test/signals.py
57+++ /dev/null
58@@ -1,3 +0,0 @@
59-from django.dispatch import Signal
60-
61-template_rendered = Signal(providing_args=["template", "context"])
62diff --git a/django/test/utils.py b/django/test/utils.py
63index 8ecb5a0..7dda41f 100644
64--- a/django/test/utils.py
65+++ b/django/test/utils.py
66@@ -4,7 +4,6 @@ import os
67 from django.conf import settings
68 from django.core import mail
69 from django.core.mail.backends import locmem
70-from django.test import signals
71 from django.template import Template
72 from django.utils.translation import deactivate
73 
74@@ -43,14 +42,6 @@ class ContextList(list):
75             return False
76         return True
77 
78-def instrumented_test_render(self, context):
79-    """
80-    An instrumented Template render method, providing a signal
81-    that can be intercepted by the test system Client
82-    """
83-    signals.template_rendered.send(sender=self, template=self, context=context)
84-    return self.nodelist.render(context)
85-
86 
87 def setup_test_environment():
88     """Perform any global pre-test setup. This involves:
89@@ -59,8 +50,8 @@ def setup_test_environment():
90         - Set the email backend to the locmem email backend.
91         - Setting the active locale to match the LANGUAGE_CODE setting.
92     """
93-    Template.original_render = Template._render
94-    Template._render = instrumented_test_render
95+    Template._original_send_rendered_signal = Template.send_rendered_signal
96+    Template.send_rendered_signal = True
97 
98     mail.original_SMTPConnection = mail.SMTPConnection
99     mail.SMTPConnection = locmem.EmailBackend
100@@ -79,8 +70,8 @@ def teardown_test_environment():
101         - Restoring the email sending functions
102 
103     """
104-    Template._render = Template.original_render
105-    del Template.original_render
106+    Template.send_rendered_signal = Template._original_send_rendered_signal
107+    del Template._original_send_rendered_signal
108 
109     mail.SMTPConnection = mail.original_SMTPConnection
110     del mail.original_SMTPConnection
111diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
112index bbbcae3..ff049f1 100644
113--- a/tests/regressiontests/templates/tests.py
114+++ b/tests/regressiontests/templates/tests.py
115@@ -16,6 +16,7 @@ import unittest
116 from django import template
117 from django.core import urlresolvers
118 from django.template import loader
119+from django.template.signals import template_rendered
120 from django.template.loaders import app_directories, filesystem, cached
121 from django.utils.translation import activate, deactivate, ugettext as _
122 from django.utils.safestring import mark_safe
123@@ -1389,5 +1390,41 @@ class TemplateTagLoading(unittest.TestCase):
124         settings.INSTALLED_APPS = ('tagsegg',)
125         t = template.Template(ttext)
126 
127+
128+class TemplateSignalTests(unittest.TestCase):
129+    def setUp(self):
130+        self._old_send = template.Template.send_rendered_signal
131+
132+        self.received = []
133+        def _handle_signal(signal, sender, template, context, **kwargs):
134+            self.received.append((template, context))
135+        template_rendered.connect(_handle_signal, weak=False, dispatch_uid='test-template-rendered')
136+
137+    def tearDown(self):
138+        template_rendered.disconnect(dispatch_uid='test-template-rendered')
139+
140+        template.Template.send_rendered_signal = self._old_send
141+
142+    def test_template_rendered_signal_on(self):
143+        "If Template.send_rendered_signal is True, template-rendering sends a template_rendered signal."
144+        template.Template.send_rendered_signal = True
145+
146+        t = template.Template("{{ stuff }}")
147+        c = template.Context({'stuff': 'something'})
148+        t.render(c)
149+
150+        self.assertEqual(self.received, [(t, c)])
151+
152+    def test_template_rendered_signal_off(self):
153+        "If Template.send_rendered_signal is False, template-rendering does not send template_rendered signal."
154+        template.Template.send_rendered_signal = False
155+
156+        t = template.Template("{{ stuff }}")
157+        c = template.Context({'stuff': 'something'})
158+        t.render(c)
159+
160+        self.assertEqual(self.received, [])
161+
162+
163 if __name__ == "__main__":
164     unittest.main()