Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #12816 -- Added a render() shortcut.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15008 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit b3d2091681d31bf2a6f8c4a1f9f1fb32393864c8 1 parent d4ef841
@freakboy3742 freakboy3742 authored
View
32 django/shortcuts/__init__.py
@@ -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 @@ def render_to_response(*args, **kwargs):
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 @@ def redirect(to, *args, **kwargs):
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 @@ def redirect(to, *args, **kwargs):
# 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 @@ def get_list_or_404(klass, *args, **kwargs):
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
+ return obj_list
+
View
5 docs/releases/1.3.txt
@@ -215,6 +215,11 @@ requests. These include:
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:
View
64 docs/topics/http/shortcuts.txt
@@ -12,6 +12,70 @@ The package ``django.shortcuts`` collects helper functions and classes that
"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``
======================
View
2  tests/regressiontests/views/templates/debug/render_test.html
@@ -1 +1 @@
-{{ foo }}.{{ bar }}.{{ baz }}.{{ processors }}
+{{ foo }}.{{ bar }}.{{ baz }}.{{ STATIC_URL }}
View
1  tests/regressiontests/views/tests/__init__.py
@@ -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 *
View
53 tests/regressiontests/views/tests/shortcuts.py
@@ -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')
+
View
8 tests/regressiontests/views/urls.py
@@ -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.
View
44 tests/regressiontests/views/views.py
@@ -1,11 +1,12 @@
import sys
-from django.http import HttpResponse, HttpResponseRedirect
from django import forms
+from django.http import HttpResponse, HttpResponseRedirect
+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 @@ def template_exception(request, n):
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')
Please sign in to comment.
Something went wrong with that request. Please try again.