Author: russellm Date: 2010-12-21 11:18:41 -0600 (Tue, 21 Dec 2010) New Revision: 15008
Added: django/trunk/tests/regressiontests/views/tests/shortcuts.py Modified: django/trunk/django/shortcuts/__init__.py django/trunk/docs/releases/1.3.txt django/trunk/docs/topics/http/shortcuts.txt django/trunk/tests/regressiontests/views/templates/debug/render_test.html django/trunk/tests/regressiontests/views/tests/__init__.py django/trunk/tests/regressiontests/views/urls.py django/trunk/tests/regressiontests/views/views.py Log: Fixed #12816 -- Added a render() shortcut. Modified: django/trunk/django/shortcuts/__init__.py =================================================================== --- django/trunk/django/shortcuts/__init__.py 2010-12-21 15:28:11 UTC (rev 15007) +++ django/trunk/django/shortcuts/__init__.py 2010-12-21 17:18:41 UTC (rev 15008) @@ -4,7 +4,7 @@ for convenience's sake. """ -from django.template import loader +from django.template import loader, RequestContext from django.http import HttpResponse, Http404 from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect from django.db.models.manager import Manager @@ -19,20 +19,31 @@ httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)} return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs) +def render(request, *args, **kwargs): + """ + Returns a HttpResponse whose content is filled with the result of calling + django.template.loader.render_to_string() with the passed arguments. + Uses a RequestContext by default. + """ + httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)} + kwargs['context_instance'] = kwargs.get('context_instance', RequestContext(request)) + return HttpResponse(loader.render_to_string(*args, **kwargs), + **httpresponse_kwargs) + def redirect(to, *args, **kwargs): """ Returns an HttpResponseRedirect to the apropriate URL for the arguments passed. - + The arguments could be: - + * A model: the model's `get_absolute_url()` function will be called. - + * A view name, possibly with arguments: `urlresolvers.reverse()` will be used to reverse-resolve the name. - + * A URL, which will be used as-is for the redirect location. - + By default issues a temporary redirect; pass permanent=True to issue a permanent redirect """ @@ -40,11 +51,11 @@ redirect_class = HttpResponsePermanentRedirect else: redirect_class = HttpResponseRedirect - + # If it's a model, use get_absolute_url() if hasattr(to, 'get_absolute_url'): return redirect_class(to.get_absolute_url()) - + # Next try a reverse URL resolution. try: return redirect_class(urlresolvers.reverse(to, args=args, kwargs=kwargs)) @@ -55,7 +66,7 @@ # If this doesn't "feel" like a URL, re-raise. if '/' not in to and '.' not in to: raise - + # Finally, fall back and assume it's a URL return redirect_class(to) @@ -101,4 +112,5 @@ obj_list = list(queryset.filter(*args, **kwargs)) if not obj_list: raise Http404('No %s matches the given query.' % queryset.model._meta.object_name) - return obj_list \ No newline at end of file + return obj_list + Modified: django/trunk/docs/releases/1.3.txt =================================================================== --- django/trunk/docs/releases/1.3.txt 2010-12-21 15:28:11 UTC (rev 15007) +++ django/trunk/docs/releases/1.3.txt 2010-12-21 17:18:41 UTC (rev 15008) @@ -215,6 +215,11 @@ making it easier to write simple template tags that require access to template context. + * A new :meth:`~django.shortcuts.render()` shortcut -- an + alternative to :meth:`~django.shortcuts.render_to_response()` + providing a :class:`~django.template.RequestContext` by + default. + .. _HTTPOnly: http://www.owasp.org/index.php/HTTPOnly .. _backwards-incompatible-changes-1.3: Modified: django/trunk/docs/topics/http/shortcuts.txt =================================================================== --- django/trunk/docs/topics/http/shortcuts.txt 2010-12-21 15:28:11 UTC (rev 15007) +++ django/trunk/docs/topics/http/shortcuts.txt 2010-12-21 17:18:41 UTC (rev 15008) @@ -12,6 +12,70 @@ "span" multiple levels of MVC. In other words, these functions/classes introduce controlled coupling for convenience's sake. +``render`` +========== + +.. function:: render(request, template[, dictionary][, context_instance][, mimetype]) + + Combines a given template with a given context dictionary and returns an + :class:`~django.http.HttpResponse` object with that rendered text. + + :func:`render()` is the same as a call to + :func:`render_to_response()` with a context_instance argument that + that forces the use of a :class:`RequestContext`. + +Required arguments +------------------ + +``request`` + The request object used to generate this response. + +``template`` + The full name of a template to use or sequence of template names. + +Optional arguments +------------------ + +``dictionary`` + A dictionary of values to add to the template context. By default, this + is an empty dictionary. If a value in the dictionary is callable, the + view will call it just before rendering the template. + +``context_instance`` + The context instance to render the template with. By default, the template + will be rendered with a ``RequestContext`` instance (filled with values from + ``request`` and ```dictionary``). + +``mimetype`` + The MIME type to use for the resulting document. Defaults to the value of + the :setting:`DEFAULT_CONTENT_TYPE` setting. + +Example +------- + +The following example renders the template ``myapp/index.html`` with the +MIME type ``application/xhtml+xml``:: + + from django.shortcuts import render_to_response + + def my_view(request): + # View code here... + return render_to_response('myapp/index.html', {"foo": "bar"}, + mimetype="application/xhtml+xml") + +This example is equivalent to:: + + from django.http import HttpResponse + from django.template import Context, loader + + def my_view(request): + # View code here... + t = loader.get_template('myapp/template.html') + c = RequestContext(request, {'foo': 'bar'}) + return HttpResponse(t.render(c), + mimetype="application/xhtml+xml") + + ``render_to_response`` ====================== Modified: django/trunk/tests/regressiontests/views/templates/debug/render_test.html =================================================================== --- django/trunk/tests/regressiontests/views/templates/debug/render_test.html 2010-12-21 15:28:11 UTC (rev 15007) +++ django/trunk/tests/regressiontests/views/templates/debug/render_test.html 2010-12-21 17:18:41 UTC (rev 15008) @@ -1 +1 @@ -{{ foo }}.{{ bar }}.{{ baz }}.{{ processors }} +{{ foo }}.{{ bar }}.{{ baz }}.{{ STATIC_URL }} Modified: django/trunk/tests/regressiontests/views/tests/__init__.py =================================================================== --- django/trunk/tests/regressiontests/views/tests/__init__.py 2010-12-21 15:28:11 UTC (rev 15007) +++ django/trunk/tests/regressiontests/views/tests/__init__.py 2010-12-21 17:18:41 UTC (rev 15008) @@ -5,5 +5,6 @@ from generic.object_list import * from generic.simple import * from i18n import * +from shortcuts import * from specials import * from static import * Added: django/trunk/tests/regressiontests/views/tests/shortcuts.py =================================================================== --- django/trunk/tests/regressiontests/views/tests/shortcuts.py (rev 0) +++ django/trunk/tests/regressiontests/views/tests/shortcuts.py 2010-12-21 17:18:41 UTC (rev 15008) @@ -0,0 +1,53 @@ +from django.conf import settings +from django.test import TestCase + +class ShortcutTests(TestCase): + def setUp(self): + self.old_STATIC_URL = settings.STATIC_URL + self.old_TEMPLATE_CONTEXT_PROCESSORS = settings.TEMPLATE_CONTEXT_PROCESSORS + + settings.STATIC_URL = '/path/to/static/media' + settings.TEMPLATE_CONTEXT_PROCESSORS = ( + 'django.core.context_processors.static' + ) + + def tearDown(self): + settings.STATIC_URL = self.old_STATIC_URL + settings.TEMPLATE_CONTEXT_PROCESSORS = self.old_TEMPLATE_CONTEXT_PROCESSORS + + def test_render_to_response(self): + response = self.client.get('/views/shortcuts/render_to_response/') + self.assertEquals(response.status_code, 200) + self.assertEquals(response.content, 'FOO.BAR..\n') + self.assertEquals(response['Content-Type'], 'text/html; charset=utf-8') + + def test_render_to_response_with_request_context(self): + response = self.client.get('/views/shortcuts/render_to_response/request_context/') + self.assertEquals(response.status_code, 200) + self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n') + self.assertEquals(response['Content-Type'], 'text/html; charset=utf-8') + + def test_render_to_response_with_mimetype(self): + response = self.client.get('/views/shortcuts/render_to_response/mimetype/') + self.assertEquals(response.status_code, 200) + self.assertEquals(response.content, 'FOO.BAR..\n') + self.assertEquals(response['Content-Type'], 'application/x-rendertest') + + def test_render(self): + response = self.client.get('/views/shortcuts/render/') + self.assertEquals(response.status_code, 200) + self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n') + self.assertEquals(response['Content-Type'], 'text/html; charset=utf-8') + + def test_render_with_base_context(self): + response = self.client.get('/views/shortcuts/render/base_context/') + self.assertEquals(response.status_code, 200) + self.assertEquals(response.content, 'FOO.BAR..\n') + self.assertEquals(response['Content-Type'], 'text/html; charset=utf-8') + + def test_render_with_mimetype(self): + response = self.client.get('/views/shortcuts/render/mimetype/') + self.assertEquals(response.status_code, 200) + self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n') + self.assertEquals(response['Content-Type'], 'application/x-rendertest') + Modified: django/trunk/tests/regressiontests/views/urls.py =================================================================== --- django/trunk/tests/regressiontests/views/urls.py 2010-12-21 15:28:11 UTC (rev 15007) +++ django/trunk/tests/regressiontests/views/urls.py 2010-12-21 17:18:41 UTC (rev 15008) @@ -143,6 +143,14 @@ urlpatterns += patterns('regressiontests.views.views', url(r'view_exception/(?P<n>\d+)/$', 'view_exception', name='view_exception'), url(r'template_exception/(?P<n>\d+)/$', 'template_exception', name='template_exception'), + + (r'^shortcuts/render_to_response/$', 'render_to_response_view'), + (r'^shortcuts/render_to_response/request_context/$', 'render_to_response_view_with_request_context'), + (r'^shortcuts/render_to_response/mimetype/$', 'render_to_response_view_with_mimetype'), + (r'^shortcuts/render/$', 'render_view'), + (r'^shortcuts/render/base_context/$', 'render_view_with_base_context'), + (r'^shortcuts/render/mimetype/$', 'render_view_with_mimetype'), + ) # simple generic views. Modified: django/trunk/tests/regressiontests/views/views.py =================================================================== --- django/trunk/tests/regressiontests/views/views.py 2010-12-21 15:28:11 UTC (rev 15007) +++ django/trunk/tests/regressiontests/views/views.py 2010-12-21 17:18:41 UTC (rev 15008) @@ -1,11 +1,12 @@ import sys +from django import forms from django.http import HttpResponse, HttpResponseRedirect -from django import forms +from django.core.urlresolvers import get_resolver +from django.shortcuts import render_to_response, render +from django.template import Context, RequestContext from django.views.debug import technical_500_response from django.views.generic.create_update import create_object -from django.core.urlresolvers import get_resolver -from django.shortcuts import render_to_response from regressiontests.views import BrokenException, except_args @@ -57,3 +58,40 @@ return render_to_response('debug/template_exception.html', {'arg': except_args[int(n)]}) +# Some views to exercise the shortcuts + +def render_to_response_view(request): + return render_to_response('debug/render_test.html', { + 'foo': 'FOO', + 'bar': 'BAR', + }) + +def render_to_response_view_with_request_context(request): + return render_to_response('debug/render_test.html', { + 'foo': 'FOO', + 'bar': 'BAR', + }, context_instance=RequestContext(request)) + +def render_to_response_view_with_mimetype(request): + return render_to_response('debug/render_test.html', { + 'foo': 'FOO', + 'bar': 'BAR', + }, mimetype='application/x-rendertest') + +def render_view(request): + return render(request, 'debug/render_test.html', { + 'foo': 'FOO', + 'bar': 'BAR', + }) + +def render_view_with_base_context(request): + return render(request, 'debug/render_test.html', { + 'foo': 'FOO', + 'bar': 'BAR', + }, context_instance=Context()) + +def render_view_with_mimetype(request): + return render(request, 'debug/render_test.html', { + 'foo': 'FOO', + 'bar': 'BAR', + }, mimetype='application/x-rendertest') -- You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-upda...@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.