Skip to content

Commit

Permalink
Fixed #15010 -- Added current_app parameter to close gap between Temp…
Browse files Browse the repository at this point in the history
…lateResponse and render method. Thanks, acdha.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15153 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
jezdez committed Jan 5, 2011
1 parent 093009b commit a389494
Show file tree
Hide file tree
Showing 9 changed files with 62 additions and 7 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -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>
Expand Down
13 changes: 12 additions & 1 deletion django/shortcuts/__init__.py
Expand Up @@ -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)


Expand Down
7 changes: 5 additions & 2 deletions django/template/response.py
Expand Up @@ -90,11 +90,14 @@ def _set_content(self, value):


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)


Expand All @@ -105,4 +108,4 @@ def resolve_context(self, context):
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)
7 changes: 6 additions & 1 deletion docs/ref/template-response.txt
Expand Up @@ -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.
Expand Down Expand Up @@ -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
===================== =====================
Expand Down
9 changes: 7 additions & 2 deletions docs/topics/http/shortcuts.txt
Expand Up @@ -15,15 +15,15 @@ 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


Combines a given template with a given context dictionary and returns an Combines a given template with a given context dictionary and returns an
: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
Expand Down Expand Up @@ -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
------- -------


Expand Down
7 changes: 7 additions & 0 deletions tests/regressiontests/templates/response.py
Expand Up @@ -172,3 +172,10 @@ def test_args(self):
'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')
8 changes: 8 additions & 0 deletions tests/regressiontests/views/tests/shortcuts.py
Expand Up @@ -38,6 +38,7 @@ def test_render(self):
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/')
Expand All @@ -56,3 +57,10 @@ def test_render_with_status(self):
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/')

3 changes: 2 additions & 1 deletion tests/regressiontests/views/urls.py
Expand Up @@ -151,7 +151,8 @@
(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.
Expand Down
14 changes: 14 additions & 0 deletions tests/regressiontests/views/views.py
Expand Up @@ -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))

0 comments on commit a389494

Please sign in to comment.