Code

Ticket #12226: 12226_r13760.2.diff

File 12226_r13760.2.diff, 7.3 KB (added by carljm, 4 years ago)
Line 
1diff --git a/django/test/client.py b/django/test/client.py
2index 08e3ff6..0588088 100644
3--- a/django/test/client.py
4+++ b/django/test/client.py
5@@ -4,6 +4,7 @@ import sys
6 import os
7 import re
8 import mimetypes
9+import warnings
10 try:
11     from cStringIO import StringIO
12 except ImportError:
13@@ -93,7 +94,7 @@ def store_rendered_templates(store, signal, sender, template, context, **kwargs)
14     """
15     Stores templates and contexts that are rendered.
16     """
17-    store.setdefault('template', []).append(template)
18+    store.setdefault('templates', []).append(template)
19     store.setdefault('context', ContextList()).append(context)
20 
21 def encode_multipart(boundary, data):
22@@ -260,16 +261,25 @@ class Client(object):
23             response.request = request
24 
25             # Add any rendered template detail to the response.
26-            # If there was only one template rendered (the most likely case),
27-            # flatten the list to a single element.
28-            for detail in ('template', 'context'):
29-                if data.get(detail):
30-                    if len(data[detail]) == 1:
31-                        setattr(response, detail, data[detail][0]);
32-                    else:
33-                        setattr(response, detail, data[detail])
34-                else:
35-                    setattr(response, detail, None)
36+            response.templates = data.get("templates", [])
37+            response.context = data.get("context")
38+
39+            # Flatten a single context. Not really necessary anymore thanks to
40+            # the __getattr__ flattening in ContextList, but has some edge-case
41+            # backwards-compatibility implications.
42+            if response.context and len(response.context) == 1:
43+                response.context = response.context[0]
44+
45+            # Provide a backwards-compatible (but pending deprecation) response.template
46+            def _get_template(self):
47+                warnings.warn("response.template is deprecated; use response.templates instead (which is always a list)",
48+                              PendingDeprecationWarning)
49+                if not self.templates:
50+                    return None
51+                elif len(self.templates) == 1:
52+                    return self.templates[0]
53+                return self.templates
54+            response.__class__.template = property(_get_template)
55 
56             # Update persistent cookie data.
57             if response.cookies:
58diff --git a/django/test/testcases.py b/django/test/testcases.py
59index 10bd6c6..1a34fd9 100644
60--- a/django/test/testcases.py
61+++ b/django/test/testcases.py
62@@ -445,7 +445,7 @@ class TransactionTestCase(unittest.TestCase):
63         if msg_prefix:
64             msg_prefix += ": "
65 
66-        template_names = [t.name for t in to_list(response.template)]
67+        template_names = [t.name for t in response.templates]
68         if not template_names:
69             self.fail(msg_prefix + "No templates used to render the response")
70         self.failUnless(template_name in template_names,
71@@ -461,7 +461,7 @@ class TransactionTestCase(unittest.TestCase):
72         if msg_prefix:
73             msg_prefix += ": "
74 
75-        template_names = [t.name for t in to_list(response.template)]
76+        template_names = [t.name for t in response.templates]
77         self.failIf(template_name in template_names,
78             msg_prefix + "Template '%s' was used unexpectedly in rendering"
79             " the response" % template_name)
80diff --git a/tests/modeltests/test_client/models.py b/tests/modeltests/test_client/models.py
81index 3052008..5cd61bf 100644
82--- a/tests/modeltests/test_client/models.py
83+++ b/tests/modeltests/test_client/models.py
84@@ -37,7 +37,7 @@ class ClientTest(TestCase):
85         # Check some response details
86         self.assertContains(response, 'This is a test')
87         self.assertEqual(response.context['var'], u'\xf2')
88-        self.assertEqual(response.template.name, 'GET Template')
89+        self.assertEqual(response.templates[0].name, 'GET Template')
90 
91     def test_get_post_view(self):
92         "GET a view that normally expects POSTs"
93@@ -45,7 +45,7 @@ class ClientTest(TestCase):
94 
95         # Check some response details
96         self.assertEqual(response.status_code, 200)
97-        self.assertEqual(response.template.name, 'Empty GET Template')
98+        self.assertEqual(response.templates[0].name, 'Empty GET Template')
99         self.assertTemplateUsed(response, 'Empty GET Template')
100         self.assertTemplateNotUsed(response, 'Empty POST Template')
101 
102@@ -55,7 +55,7 @@ class ClientTest(TestCase):
103 
104         # Check some response details
105         self.assertEqual(response.status_code, 200)
106-        self.assertEqual(response.template.name, 'Empty POST Template')
107+        self.assertEqual(response.templates[0].name, 'Empty POST Template')
108         self.assertTemplateNotUsed(response, 'Empty GET Template')
109         self.assertTemplateUsed(response, 'Empty POST Template')
110 
111@@ -69,7 +69,7 @@ class ClientTest(TestCase):
112         # Check some response details
113         self.assertEqual(response.status_code, 200)
114         self.assertEqual(response.context['data'], '37')
115-        self.assertEqual(response.template.name, 'POST Template')
116+        self.assertEqual(response.templates[0].name, 'POST Template')
117         self.failUnless('Data received' in response.content)
118 
119     def test_response_headers(self):
120@@ -84,7 +84,7 @@ class ClientTest(TestCase):
121         response = self.client.post("/test_client/raw_post_view/", test_doc,
122                                     content_type="text/xml")
123         self.assertEqual(response.status_code, 200)
124-        self.assertEqual(response.template.name, "Book template")
125+        self.assertEqual(response.templates[0].name, "Book template")
126         self.assertEqual(response.content, "Blink - Malcolm Gladwell")
127 
128     def test_redirect(self):
129diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py
130index 22b59e5..20ed3af 100644
131--- a/tests/regressiontests/test_client_regress/models.py
132+++ b/tests/regressiontests/test_client_regress/models.py
133@@ -9,7 +9,7 @@ from django.test import Client, TestCase
134 from django.test.utils import ContextList
135 from django.core.urlresolvers import reverse
136 from django.core.exceptions import SuspiciousOperation
137-from django.template import TemplateDoesNotExist, TemplateSyntaxError, Context
138+from django.template import TemplateDoesNotExist, TemplateSyntaxError, Context, Template
139 from django.template import loader
140 from django.test.client import encode_file
141 
142@@ -861,3 +861,18 @@ class RequestHeadersTest(TestCase):
143         self.assertEquals(response.content, "HTTP_X_ARG_CHECK: Testing 123")
144         self.assertRedirects(response, '/test_client_regress/check_headers/',
145             status_code=301, target_status_code=200)
146+
147+class ResponseTemplateDeprecationTests(TestCase):
148+    """
149+    Response.template still works backwards-compatibly, but with pending deprecation warning. Refs #12226.
150+
151+    """
152+    def test_response_template_data(self):
153+        response = self.client.get("/test_client_regress/request_data/", data={'foo':'whiz'})
154+        self.assertEqual(response.template.__class__, Template)
155+        self.assertEqual(response.template.name, 'base.html')
156+
157+    def test_response_no_template(self):
158+        response = self.client.get("/test_client_regress/request_methods/")
159+        self.assertEqual(response.template, None)
160+