1 | From 18bb674234e836ba3a8aa6b63c9001100a03b7d0 Mon Sep 17 00:00:00 2001
|
---|
2 | From: Chris Adams <chris@improbable.org>
|
---|
3 | Date: Mon, 3 Jan 2011 11:57:26 -0500
|
---|
4 | Subject: [PATCH 1/5] TemplateResponse: accept a current_app parameter for RequestContext
|
---|
5 |
|
---|
6 | This simplifies cases such as the Django admin conversion in #15008 where the
|
---|
7 | need to set current_app requires an extra import and creating the RequestContext
|
---|
8 | manually.
|
---|
9 | ---
|
---|
10 | django/template/response.py | 7 +++++--
|
---|
11 | tests/regressiontests/templates/response.py | 7 +++++++
|
---|
12 | 2 files changed, 12 insertions(+), 2 deletions(-)
|
---|
13 |
|
---|
14 | diff --git a/django/template/response.py b/django/template/response.py
|
---|
15 | index d89fee0..629461a 100644
|
---|
16 | --- a/django/template/response.py
|
---|
17 | +++ b/django/template/response.py
|
---|
18 | @@ -90,11 +90,14 @@ class SimpleTemplateResponse(HttpResponse):
|
---|
19 |
|
---|
20 | class TemplateResponse(SimpleTemplateResponse):
|
---|
21 | def __init__(self, request, template, context=None, mimetype=None,
|
---|
22 | - status=None, content_type=None):
|
---|
23 | + status=None, content_type=None, current_app=None):
|
---|
24 | # self.request gets over-written by django.test.client.Client - and
|
---|
25 | # unlike context_data and template_name the _request should not
|
---|
26 | # be considered part of the public API.
|
---|
27 | self._request = request
|
---|
28 | + # As a convenience we'll allow callers to provide current_app without
|
---|
29 | + # having to avoid needing to create the RequestContext directly
|
---|
30 | + self._current_app = current_app
|
---|
31 | super(TemplateResponse, self).__init__(
|
---|
32 | template, context, mimetype, status, content_type)
|
---|
33 |
|
---|
34 | @@ -105,4 +108,4 @@ class TemplateResponse(SimpleTemplateResponse):
|
---|
35 | if isinstance(context, Context):
|
---|
36 | return context
|
---|
37 | else:
|
---|
38 | - return RequestContext(self._request, context)
|
---|
39 | + return RequestContext(self._request, context, current_app=self._current_app)
|
---|
40 | diff --git a/tests/regressiontests/templates/response.py b/tests/regressiontests/templates/response.py
|
---|
41 | index 8bdf7f4..2f0d2c7 100644
|
---|
42 | --- a/tests/regressiontests/templates/response.py
|
---|
43 | +++ b/tests/regressiontests/templates/response.py
|
---|
44 | @@ -172,3 +172,10 @@ class TemplateResponseTest(BaseTemplateResponseTest):
|
---|
45 | 'application/json', 504)
|
---|
46 | self.assertEqual(response['content-type'], 'application/json')
|
---|
47 | self.assertEqual(response.status_code, 504)
|
---|
48 | +
|
---|
49 | + def test_custom_app(self):
|
---|
50 | + response = self._response('{{ foo }}', current_app="foobar")
|
---|
51 | +
|
---|
52 | + rc = response.resolve_context(response.context_data)
|
---|
53 | +
|
---|
54 | + self.assertEqual(rc.current_app, 'foobar')
|
---|
55 | --
|
---|
56 | 1.7.0.2
|
---|
57 |
|
---|
58 |
|
---|
59 | From fc912c9def744d5a504db15a8061610eee899597 Mon Sep 17 00:00:00 2001
|
---|
60 | From: Chris Adams <chris@improbable.org>
|
---|
61 | Date: Mon, 3 Jan 2011 21:33:30 -0500
|
---|
62 | Subject: [PATCH 2/5] Add current_app support to shortcuts.render
|
---|
63 |
|
---|
64 | This parallels the earlier change to TemplateResponse, providing a convenient way to pass current_app without having to instantiate a RequestContext by hand.
|
---|
65 |
|
---|
66 | See http://code.djangoproject.com/ticket/15010
|
---|
67 | ---
|
---|
68 | django/shortcuts/__init__.py | 10 +++++++++-
|
---|
69 | tests/regressiontests/views/tests/shortcuts.py | 4 ++++
|
---|
70 | tests/regressiontests/views/urls.py | 2 +-
|
---|
71 | tests/regressiontests/views/views.py | 6 ++++++
|
---|
72 | 4 files changed, 20 insertions(+), 2 deletions(-)
|
---|
73 |
|
---|
74 | diff --git a/django/shortcuts/__init__.py b/django/shortcuts/__init__.py
|
---|
75 | index b7d69b5..6347d3f 100644
|
---|
76 | --- a/django/shortcuts/__init__.py
|
---|
77 | +++ b/django/shortcuts/__init__.py
|
---|
78 | @@ -29,7 +29,15 @@ def render(request, *args, **kwargs):
|
---|
79 | 'content_type': kwargs.pop('content_type', None),
|
---|
80 | 'status': kwargs.pop('status', None),
|
---|
81 | }
|
---|
82 | - kwargs['context_instance'] = kwargs.get('context_instance', RequestContext(request))
|
---|
83 | +
|
---|
84 | + if 'context_instance' in kwargs:
|
---|
85 | + context_instance = kwargs.pop("context_instance")
|
---|
86 | + else:
|
---|
87 | + current_app = kwargs.pop("current_app", None)
|
---|
88 | + context_instance = RequestContext(request, current_app=current_app)
|
---|
89 | +
|
---|
90 | + kwargs['context_instance'] = context_instance
|
---|
91 | +
|
---|
92 | return HttpResponse(loader.render_to_string(*args, **kwargs),
|
---|
93 | **httpresponse_kwargs)
|
---|
94 |
|
---|
95 | diff --git a/tests/regressiontests/views/tests/shortcuts.py b/tests/regressiontests/views/tests/shortcuts.py
|
---|
96 | index 3f260fe..fa8408c 100644
|
---|
97 | --- a/tests/regressiontests/views/tests/shortcuts.py
|
---|
98 | +++ b/tests/regressiontests/views/tests/shortcuts.py
|
---|
99 | @@ -56,3 +56,7 @@ class ShortcutTests(TestCase):
|
---|
100 | self.assertEquals(response.status_code, 403)
|
---|
101 | self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n')
|
---|
102 |
|
---|
103 | + def test_render_with_current_app(self):
|
---|
104 | + response = self.client.get('/views/shortcuts/render/current_app/')
|
---|
105 | + self.assertEquals(response.context.current_app, "foobar_app")
|
---|
106 | +
|
---|
107 | diff --git a/tests/regressiontests/views/urls.py b/tests/regressiontests/views/urls.py
|
---|
108 | index 7cba5f6..7dad098 100644
|
---|
109 | --- a/tests/regressiontests/views/urls.py
|
---|
110 | +++ b/tests/regressiontests/views/urls.py
|
---|
111 | @@ -151,7 +151,7 @@ urlpatterns += patterns('regressiontests.views.views',
|
---|
112 | (r'^shortcuts/render/base_context/$', 'render_view_with_base_context'),
|
---|
113 | (r'^shortcuts/render/content_type/$', 'render_view_with_content_type'),
|
---|
114 | (r'^shortcuts/render/status/$', 'render_view_with_status'),
|
---|
115 | -
|
---|
116 | + (r'^shortcuts/render/current_app/$', 'render_view_with_current_app'),
|
---|
117 | )
|
---|
118 |
|
---|
119 | # simple generic views.
|
---|
120 | diff --git a/tests/regressiontests/views/views.py b/tests/regressiontests/views/views.py
|
---|
121 | index ec017bd..9c9b4c5 100644
|
---|
122 | --- a/tests/regressiontests/views/views.py
|
---|
123 | +++ b/tests/regressiontests/views/views.py
|
---|
124 | @@ -101,3 +101,9 @@ def render_view_with_status(request):
|
---|
125 | 'foo': 'FOO',
|
---|
126 | 'bar': 'BAR',
|
---|
127 | }, status=403)
|
---|
128 | +
|
---|
129 | +def render_view_with_current_app(request):
|
---|
130 | + return render(request, 'debug/render_test.html', {
|
---|
131 | + 'foo': 'FOO',
|
---|
132 | + 'bar': 'BAR',
|
---|
133 | + }, current_app="foobar_app")
|
---|
134 | --
|
---|
135 | 1.7.0.2
|
---|
136 |
|
---|
137 |
|
---|
138 | From d1024ace8965230d5eac7d2a7a8cefeeefc3b36d Mon Sep 17 00:00:00 2001
|
---|
139 | From: Chris Adams <chris@improbable.org>
|
---|
140 | Date: Mon, 3 Jan 2011 21:46:51 -0500
|
---|
141 | Subject: [PATCH 3/5] Documentation for current_app on render shortcut and TemplateResponse
|
---|
142 |
|
---|
143 | Basic documentation and a pointer to the namespaced URL resolution strategy.
|
---|
144 | ---
|
---|
145 | docs/ref/template-response.txt | 7 ++++++-
|
---|
146 | docs/topics/http/shortcuts.txt | 9 +++++++--
|
---|
147 | 2 files changed, 13 insertions(+), 3 deletions(-)
|
---|
148 |
|
---|
149 | diff --git a/docs/ref/template-response.txt b/docs/ref/template-response.txt
|
---|
150 | index 3b136b6..d4fe2c4 100644
|
---|
151 | --- a/docs/ref/template-response.txt
|
---|
152 | +++ b/docs/ref/template-response.txt
|
---|
153 | @@ -129,7 +129,7 @@ TemplateResponse objects
|
---|
154 | Methods
|
---|
155 | -------
|
---|
156 |
|
---|
157 | -.. method:: TemplateResponse.__init__(request, template, context=None, mimetype=None, status=None, content_type=None)
|
---|
158 | +.. method:: TemplateResponse.__init__(request, template, context=None, mimetype=None, status=None, content_type=None, current_app=None)
|
---|
159 |
|
---|
160 | Instantiates an ``TemplateResponse`` object with the given
|
---|
161 | template, context, MIME type and HTTP status.
|
---|
162 | @@ -158,6 +158,11 @@ Methods
|
---|
163 | ``content_type`` is used. If neither is given,
|
---|
164 | :setting:`DEFAULT_CONTENT_TYPE` is used.
|
---|
165 |
|
---|
166 | + ``current_app``
|
---|
167 | + A hint indicating which application contains the current view. See the
|
---|
168 | + :ref:`namespaced URL resolution strategy <topics-http-reversing-url-namespaces>`
|
---|
169 | + for more information.
|
---|
170 | +
|
---|
171 |
|
---|
172 | The rendering process
|
---|
173 | =====================
|
---|
174 | diff --git a/docs/topics/http/shortcuts.txt b/docs/topics/http/shortcuts.txt
|
---|
175 | index 1c1dc9e..9d72521 100644
|
---|
176 | --- a/docs/topics/http/shortcuts.txt
|
---|
177 | +++ b/docs/topics/http/shortcuts.txt
|
---|
178 | @@ -15,7 +15,7 @@ introduce controlled coupling for convenience's sake.
|
---|
179 | ``render``
|
---|
180 | ==========
|
---|
181 |
|
---|
182 | -.. function:: render(request, template[, dictionary][, context_instance][, content_type][, status])
|
---|
183 | +.. function:: render(request, template[, dictionary][, context_instance][, content_type][, status][, current_app])
|
---|
184 |
|
---|
185 | .. versionadded:: 1.3
|
---|
186 |
|
---|
187 | @@ -23,7 +23,7 @@ introduce controlled coupling for convenience's sake.
|
---|
188 | :class:`~django.http.HttpResponse` object with that rendered text.
|
---|
189 |
|
---|
190 | :func:`render()` is the same as a call to
|
---|
191 | - :func:`render_to_response()` with a context_instance argument that
|
---|
192 | + :func:`render_to_response()` with a `context_instance` argument that
|
---|
193 | that forces the use of a :class:`RequestContext`.
|
---|
194 |
|
---|
195 | Required arguments
|
---|
196 | @@ -55,6 +55,11 @@ Optional arguments
|
---|
197 | ``status``
|
---|
198 | The status code for the response. Defaults to ``200``.
|
---|
199 |
|
---|
200 | +``current_app``
|
---|
201 | + A hint indicating which application contains the current view. See the
|
---|
202 | + :ref:`namespaced URL resolution strategy <topics-http-reversing-url-namespaces>`
|
---|
203 | + for more information.
|
---|
204 | +
|
---|
205 | Example
|
---|
206 | -------
|
---|
207 |
|
---|
208 | --
|
---|
209 | 1.7.0.2
|
---|
210 |
|
---|
211 |
|
---|
212 | From 3525c20f5c7375c3ab13b5a509b0be6c588a0254 Mon Sep 17 00:00:00 2001
|
---|
213 | From: Chris Adams <chris@improbable.org>
|
---|
214 | Date: Mon, 3 Jan 2011 22:05:13 -0500
|
---|
215 | Subject: [PATCH 4/5] render(): Added a simple current_app sanity check
|
---|
216 |
|
---|
217 | This enforces a simple policy: render() will only set current_app on
|
---|
218 | RequestContexts which it creates.
|
---|
219 | ---
|
---|
220 | django/shortcuts/__init__.py | 2 ++
|
---|
221 | tests/regressiontests/views/tests/shortcuts.py | 3 +++
|
---|
222 | tests/regressiontests/views/urls.py | 1 +
|
---|
223 | tests/regressiontests/views/views.py | 8 ++++++++
|
---|
224 | 4 files changed, 14 insertions(+), 0 deletions(-)
|
---|
225 |
|
---|
226 | diff --git a/django/shortcuts/__init__.py b/django/shortcuts/__init__.py
|
---|
227 | index 6347d3f..98116f0 100644
|
---|
228 | --- a/django/shortcuts/__init__.py
|
---|
229 | +++ b/django/shortcuts/__init__.py
|
---|
230 | @@ -32,6 +32,8 @@ def render(request, *args, **kwargs):
|
---|
231 |
|
---|
232 | if 'context_instance' in kwargs:
|
---|
233 | context_instance = kwargs.pop("context_instance")
|
---|
234 | + if kwargs.get("current_app", None):
|
---|
235 | + raise ValueError("If you provide a context_instance you must set its current_app before calling render()")
|
---|
236 | else:
|
---|
237 | current_app = kwargs.pop("current_app", None)
|
---|
238 | context_instance = RequestContext(request, current_app=current_app)
|
---|
239 | diff --git a/tests/regressiontests/views/tests/shortcuts.py b/tests/regressiontests/views/tests/shortcuts.py
|
---|
240 | index fa8408c..c974348 100644
|
---|
241 | --- a/tests/regressiontests/views/tests/shortcuts.py
|
---|
242 | +++ b/tests/regressiontests/views/tests/shortcuts.py
|
---|
243 | @@ -60,3 +60,6 @@ class ShortcutTests(TestCase):
|
---|
244 | response = self.client.get('/views/shortcuts/render/current_app/')
|
---|
245 | self.assertEquals(response.context.current_app, "foobar_app")
|
---|
246 |
|
---|
247 | + def test_render_with_current_app_conflict(self):
|
---|
248 | + self.assertRaises(ValueError, self.client.get, '/views/shortcuts/render/current_app_conflict/')
|
---|
249 | +
|
---|
250 | diff --git a/tests/regressiontests/views/urls.py b/tests/regressiontests/views/urls.py
|
---|
251 | index 7dad098..a170efb 100644
|
---|
252 | --- a/tests/regressiontests/views/urls.py
|
---|
253 | +++ b/tests/regressiontests/views/urls.py
|
---|
254 | @@ -152,6 +152,7 @@ urlpatterns += patterns('regressiontests.views.views',
|
---|
255 | (r'^shortcuts/render/content_type/$', 'render_view_with_content_type'),
|
---|
256 | (r'^shortcuts/render/status/$', 'render_view_with_status'),
|
---|
257 | (r'^shortcuts/render/current_app/$', 'render_view_with_current_app'),
|
---|
258 | + (r'^shortcuts/render/current_app_conflict/$', 'render_view_with_current_app_conflict'),
|
---|
259 | )
|
---|
260 |
|
---|
261 | # simple generic views.
|
---|
262 | diff --git a/tests/regressiontests/views/views.py b/tests/regressiontests/views/views.py
|
---|
263 | index 9c9b4c5..e4e7c3d 100644
|
---|
264 | --- a/tests/regressiontests/views/views.py
|
---|
265 | +++ b/tests/regressiontests/views/views.py
|
---|
266 | @@ -107,3 +107,11 @@ def render_view_with_current_app(request):
|
---|
267 | 'foo': 'FOO',
|
---|
268 | 'bar': 'BAR',
|
---|
269 | }, current_app="foobar_app")
|
---|
270 | +
|
---|
271 | +def render_view_with_current_app_conflict(request):
|
---|
272 | + # This should fail because we don't passing both a current_app and
|
---|
273 | + # context_instance:
|
---|
274 | + return render(request, 'debug/render_test.html', {
|
---|
275 | + 'foo': 'FOO',
|
---|
276 | + 'bar': 'BAR',
|
---|
277 | + }, current_app="foobar_app", context_instance=RequestContext(request))
|
---|
278 | --
|
---|
279 | 1.7.0.2
|
---|
280 |
|
---|
281 |
|
---|
282 | From 67b08c22bffeb7ab4014fa22b99a67f3c684240e Mon Sep 17 00:00:00 2001
|
---|
283 | From: Chris Adams <chris@improbable.org>
|
---|
284 | Date: Mon, 3 Jan 2011 22:13:48 -0500
|
---|
285 | Subject: [PATCH 5/5] shortcuts.render(): test update
|
---|
286 |
|
---|
287 | * Add positive assertion that current_app is not accidentally set
|
---|
288 | ---
|
---|
289 | tests/regressiontests/views/tests/shortcuts.py | 1 +
|
---|
290 | 1 files changed, 1 insertions(+), 0 deletions(-)
|
---|
291 |
|
---|
292 | diff --git a/tests/regressiontests/views/tests/shortcuts.py b/tests/regressiontests/views/tests/shortcuts.py
|
---|
293 | index c974348..c5f664e 100644
|
---|
294 | --- a/tests/regressiontests/views/tests/shortcuts.py
|
---|
295 | +++ b/tests/regressiontests/views/tests/shortcuts.py
|
---|
296 | @@ -38,6 +38,7 @@ class ShortcutTests(TestCase):
|
---|
297 | self.assertEquals(response.status_code, 200)
|
---|
298 | self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n')
|
---|
299 | self.assertEquals(response['Content-Type'], 'text/html; charset=utf-8')
|
---|
300 | + self.assertEquals(response.context.current_app, None)
|
---|
301 |
|
---|
302 | def test_render_with_base_context(self):
|
---|
303 | response = self.client.get('/views/shortcuts/render/base_context/')
|
---|
304 | --
|
---|
305 | 1.7.0.2
|
---|
306 |
|
---|