Fixed #15010 -- Added current_app parameter to close gap between TemplateResponse and render method. Thanks, acdha.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@15153 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
093009bf1f
commit
a3894945b6
1
AUTHORS
1
AUTHORS
|
@ -33,6 +33,7 @@ people who have submitted patches, reported bugs, added translations, helped
|
||||||
answer newbie questions, and generally made Django that much better:
|
answer newbie questions, and generally made Django that much better:
|
||||||
|
|
||||||
Gisle Aas <gisle@aas.no>
|
Gisle Aas <gisle@aas.no>
|
||||||
|
Chris Adams
|
||||||
ajs <adi@sieker.info>
|
ajs <adi@sieker.info>
|
||||||
alang@bright-green.com
|
alang@bright-green.com
|
||||||
A S Alam <aalam@users.sf.net>
|
A S Alam <aalam@users.sf.net>
|
||||||
|
|
|
@ -29,7 +29,18 @@ def render(request, *args, **kwargs):
|
||||||
'content_type': kwargs.pop('content_type', None),
|
'content_type': kwargs.pop('content_type', None),
|
||||||
'status': kwargs.pop('status', None),
|
'status': kwargs.pop('status', None),
|
||||||
}
|
}
|
||||||
kwargs['context_instance'] = kwargs.get('context_instance', RequestContext(request))
|
|
||||||
|
if 'context_instance' in kwargs:
|
||||||
|
context_instance = kwargs.pop('context_instance')
|
||||||
|
if kwargs.get('current_app', None):
|
||||||
|
raise ValueError('If you provide a context_instance you must '
|
||||||
|
'set its current_app before calling render()')
|
||||||
|
else:
|
||||||
|
current_app = kwargs.pop('current_app', None)
|
||||||
|
context_instance = RequestContext(request, current_app=current_app)
|
||||||
|
|
||||||
|
kwargs['context_instance'] = context_instance
|
||||||
|
|
||||||
return HttpResponse(loader.render_to_string(*args, **kwargs),
|
return HttpResponse(loader.render_to_string(*args, **kwargs),
|
||||||
**httpresponse_kwargs)
|
**httpresponse_kwargs)
|
||||||
|
|
||||||
|
|
|
@ -90,11 +90,14 @@ class SimpleTemplateResponse(HttpResponse):
|
||||||
|
|
||||||
class TemplateResponse(SimpleTemplateResponse):
|
class TemplateResponse(SimpleTemplateResponse):
|
||||||
def __init__(self, request, template, context=None, mimetype=None,
|
def __init__(self, request, template, context=None, mimetype=None,
|
||||||
status=None, content_type=None):
|
status=None, content_type=None, current_app=None):
|
||||||
# self.request gets over-written by django.test.client.Client - and
|
# self.request gets over-written by django.test.client.Client - and
|
||||||
# unlike context_data and template_name the _request should not
|
# unlike context_data and template_name the _request should not
|
||||||
# be considered part of the public API.
|
# be considered part of the public API.
|
||||||
self._request = request
|
self._request = request
|
||||||
|
# As a convenience we'll allow callers to provide current_app without
|
||||||
|
# having to avoid needing to create the RequestContext directly
|
||||||
|
self._current_app = current_app
|
||||||
super(TemplateResponse, self).__init__(
|
super(TemplateResponse, self).__init__(
|
||||||
template, context, mimetype, status, content_type)
|
template, context, mimetype, status, content_type)
|
||||||
|
|
||||||
|
@ -105,4 +108,4 @@ class TemplateResponse(SimpleTemplateResponse):
|
||||||
if isinstance(context, Context):
|
if isinstance(context, Context):
|
||||||
return context
|
return context
|
||||||
else:
|
else:
|
||||||
return RequestContext(self._request, context)
|
return RequestContext(self._request, context, current_app=self._current_app)
|
||||||
|
|
|
@ -129,7 +129,7 @@ TemplateResponse objects
|
||||||
Methods
|
Methods
|
||||||
-------
|
-------
|
||||||
|
|
||||||
.. method:: TemplateResponse.__init__(request, template, context=None, mimetype=None, status=None, content_type=None)
|
.. method:: TemplateResponse.__init__(request, template, context=None, mimetype=None, status=None, content_type=None, current_app=None)
|
||||||
|
|
||||||
Instantiates an ``TemplateResponse`` object with the given
|
Instantiates an ``TemplateResponse`` object with the given
|
||||||
template, context, MIME type and HTTP status.
|
template, context, MIME type and HTTP status.
|
||||||
|
@ -158,6 +158,11 @@ Methods
|
||||||
``content_type`` is used. If neither is given,
|
``content_type`` is used. If neither is given,
|
||||||
:setting:`DEFAULT_CONTENT_TYPE` is used.
|
:setting:`DEFAULT_CONTENT_TYPE` is used.
|
||||||
|
|
||||||
|
``current_app``
|
||||||
|
A hint indicating which application contains the current view. See the
|
||||||
|
:ref:`namespaced URL resolution strategy <topics-http-reversing-url-namespaces>`
|
||||||
|
for more information.
|
||||||
|
|
||||||
|
|
||||||
The rendering process
|
The rendering process
|
||||||
=====================
|
=====================
|
||||||
|
|
|
@ -15,7 +15,7 @@ introduce controlled coupling for convenience's sake.
|
||||||
``render``
|
``render``
|
||||||
==========
|
==========
|
||||||
|
|
||||||
.. function:: render(request, template[, dictionary][, context_instance][, content_type][, status])
|
.. function:: render(request, template[, dictionary][, context_instance][, content_type][, status][, current_app])
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ introduce controlled coupling for convenience's sake.
|
||||||
:class:`~django.http.HttpResponse` object with that rendered text.
|
:class:`~django.http.HttpResponse` object with that rendered text.
|
||||||
|
|
||||||
:func:`render()` is the same as a call to
|
:func:`render()` is the same as a call to
|
||||||
:func:`render_to_response()` with a context_instance argument that
|
:func:`render_to_response()` with a `context_instance` argument that
|
||||||
that forces the use of a :class:`RequestContext`.
|
that forces the use of a :class:`RequestContext`.
|
||||||
|
|
||||||
Required arguments
|
Required arguments
|
||||||
|
@ -55,6 +55,11 @@ Optional arguments
|
||||||
``status``
|
``status``
|
||||||
The status code for the response. Defaults to ``200``.
|
The status code for the response. Defaults to ``200``.
|
||||||
|
|
||||||
|
``current_app``
|
||||||
|
A hint indicating which application contains the current view. See the
|
||||||
|
:ref:`namespaced URL resolution strategy <topics-http-reversing-url-namespaces>`
|
||||||
|
for more information.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
|
@ -172,3 +172,10 @@ class TemplateResponseTest(BaseTemplateResponseTest):
|
||||||
'application/json', 504)
|
'application/json', 504)
|
||||||
self.assertEqual(response['content-type'], 'application/json')
|
self.assertEqual(response['content-type'], 'application/json')
|
||||||
self.assertEqual(response.status_code, 504)
|
self.assertEqual(response.status_code, 504)
|
||||||
|
|
||||||
|
def test_custom_app(self):
|
||||||
|
response = self._response('{{ foo }}', current_app="foobar")
|
||||||
|
|
||||||
|
rc = response.resolve_context(response.context_data)
|
||||||
|
|
||||||
|
self.assertEqual(rc.current_app, 'foobar')
|
||||||
|
|
|
@ -38,6 +38,7 @@ class ShortcutTests(TestCase):
|
||||||
self.assertEquals(response.status_code, 200)
|
self.assertEquals(response.status_code, 200)
|
||||||
self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n')
|
self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n')
|
||||||
self.assertEquals(response['Content-Type'], 'text/html; charset=utf-8')
|
self.assertEquals(response['Content-Type'], 'text/html; charset=utf-8')
|
||||||
|
self.assertEquals(response.context.current_app, None)
|
||||||
|
|
||||||
def test_render_with_base_context(self):
|
def test_render_with_base_context(self):
|
||||||
response = self.client.get('/views/shortcuts/render/base_context/')
|
response = self.client.get('/views/shortcuts/render/base_context/')
|
||||||
|
@ -56,3 +57,10 @@ class ShortcutTests(TestCase):
|
||||||
self.assertEquals(response.status_code, 403)
|
self.assertEquals(response.status_code, 403)
|
||||||
self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n')
|
self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n')
|
||||||
|
|
||||||
|
def test_render_with_current_app(self):
|
||||||
|
response = self.client.get('/views/shortcuts/render/current_app/')
|
||||||
|
self.assertEquals(response.context.current_app, "foobar_app")
|
||||||
|
|
||||||
|
def test_render_with_current_app_conflict(self):
|
||||||
|
self.assertRaises(ValueError, self.client.get, '/views/shortcuts/render/current_app_conflict/')
|
||||||
|
|
||||||
|
|
|
@ -151,7 +151,8 @@ urlpatterns += patterns('regressiontests.views.views',
|
||||||
(r'^shortcuts/render/base_context/$', 'render_view_with_base_context'),
|
(r'^shortcuts/render/base_context/$', 'render_view_with_base_context'),
|
||||||
(r'^shortcuts/render/content_type/$', 'render_view_with_content_type'),
|
(r'^shortcuts/render/content_type/$', 'render_view_with_content_type'),
|
||||||
(r'^shortcuts/render/status/$', 'render_view_with_status'),
|
(r'^shortcuts/render/status/$', 'render_view_with_status'),
|
||||||
|
(r'^shortcuts/render/current_app/$', 'render_view_with_current_app'),
|
||||||
|
(r'^shortcuts/render/current_app_conflict/$', 'render_view_with_current_app_conflict'),
|
||||||
)
|
)
|
||||||
|
|
||||||
# simple generic views.
|
# simple generic views.
|
||||||
|
|
|
@ -101,3 +101,17 @@ def render_view_with_status(request):
|
||||||
'foo': 'FOO',
|
'foo': 'FOO',
|
||||||
'bar': 'BAR',
|
'bar': 'BAR',
|
||||||
}, status=403)
|
}, status=403)
|
||||||
|
|
||||||
|
def render_view_with_current_app(request):
|
||||||
|
return render(request, 'debug/render_test.html', {
|
||||||
|
'foo': 'FOO',
|
||||||
|
'bar': 'BAR',
|
||||||
|
}, current_app="foobar_app")
|
||||||
|
|
||||||
|
def render_view_with_current_app_conflict(request):
|
||||||
|
# This should fail because we don't passing both a current_app and
|
||||||
|
# context_instance:
|
||||||
|
return render(request, 'debug/render_test.html', {
|
||||||
|
'foo': 'FOO',
|
||||||
|
'bar': 'BAR',
|
||||||
|
}, current_app="foobar_app", context_instance=RequestContext(request))
|
||||||
|
|
Loading…
Reference in New Issue