Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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
Russell Keith-Magee authored December 21, 2010
32  django/shortcuts/__init__.py
@@ -4,7 +4,7 @@
4 4
 for convenience's sake.
5 5
 """
6 6
 
7  
-from django.template import loader
  7
+from django.template import loader, RequestContext
8 8
 from django.http import HttpResponse, Http404
9 9
 from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
10 10
 from django.db.models.manager import Manager
@@ -19,20 +19,31 @@ def render_to_response(*args, **kwargs):
19 19
     httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
20 20
     return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
21 21
 
  22
+def render(request, *args, **kwargs):
  23
+    """
  24
+    Returns a HttpResponse whose content is filled with the result of calling
  25
+    django.template.loader.render_to_string() with the passed arguments.
  26
+    Uses a RequestContext by default.
  27
+    """
  28
+    httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
  29
+    kwargs['context_instance'] = kwargs.get('context_instance', RequestContext(request))
  30
+    return HttpResponse(loader.render_to_string(*args, **kwargs),
  31
+                        **httpresponse_kwargs)
  32
+
22 33
 def redirect(to, *args, **kwargs):
23 34
     """
24 35
     Returns an HttpResponseRedirect to the apropriate URL for the arguments
25 36
     passed.
26  
-    
  37
+
27 38
     The arguments could be:
28  
-    
  39
+
29 40
         * A model: the model's `get_absolute_url()` function will be called.
30  
-    
  41
+
31 42
         * A view name, possibly with arguments: `urlresolvers.reverse()` will
32 43
           be used to reverse-resolve the name.
33  
-         
  44
+
34 45
         * A URL, which will be used as-is for the redirect location.
35  
-        
  46
+
36 47
     By default issues a temporary redirect; pass permanent=True to issue a
37 48
     permanent redirect
38 49
     """
@@ -40,11 +51,11 @@ def redirect(to, *args, **kwargs):
40 51
         redirect_class = HttpResponsePermanentRedirect
41 52
     else:
42 53
         redirect_class = HttpResponseRedirect
43  
-    
  54
+
44 55
     # If it's a model, use get_absolute_url()
45 56
     if hasattr(to, 'get_absolute_url'):
46 57
         return redirect_class(to.get_absolute_url())
47  
-    
  58
+
48 59
     # Next try a reverse URL resolution.
49 60
     try:
50 61
         return redirect_class(urlresolvers.reverse(to, args=args, kwargs=kwargs))
@@ -55,7 +66,7 @@ def redirect(to, *args, **kwargs):
55 66
         # If this doesn't "feel" like a URL, re-raise.
56 67
         if '/' not in to and '.' not in to:
57 68
             raise
58  
-        
  69
+
59 70
     # Finally, fall back and assume it's a URL
60 71
     return redirect_class(to)
61 72
 
@@ -101,4 +112,5 @@ def get_list_or_404(klass, *args, **kwargs):
101 112
     obj_list = list(queryset.filter(*args, **kwargs))
102 113
     if not obj_list:
103 114
         raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
104  
-    return obj_list
  115
+    return obj_list
  116
+
5  docs/releases/1.3.txt
@@ -215,6 +215,11 @@ requests. These include:
215 215
       making it easier to write simple template tags that require
216 216
       access to template context.
217 217
 
  218
+    * A new :meth:`~django.shortcuts.render()` shortcut -- an
  219
+      alternative to :meth:`~django.shortcuts.render_to_response()`
  220
+      providing a :class:`~django.template.RequestContext` by
  221
+      default.
  222
+
218 223
 .. _HTTPOnly: http://www.owasp.org/index.php/HTTPOnly
219 224
 
220 225
 .. _backwards-incompatible-changes-1.3:
64  docs/topics/http/shortcuts.txt
@@ -12,6 +12,70 @@ The package ``django.shortcuts`` collects helper functions and classes that
12 12
 "span" multiple levels of MVC. In other words, these functions/classes
13 13
 introduce controlled coupling for convenience's sake.
14 14
 
  15
+``render``
  16
+==========
  17
+
  18
+.. function:: render(request, template[, dictionary][, context_instance][, mimetype])
  19
+
  20
+   Combines a given template with a given context dictionary and returns an
  21
+   :class:`~django.http.HttpResponse` object with that rendered text.
  22
+
  23
+   :func:`render()` is the same as a call to
  24
+   :func:`render_to_response()` with a context_instance argument that
  25
+   that forces the use of a :class:`RequestContext`.
  26
+
  27
+Required arguments
  28
+------------------
  29
+
  30
+``request``
  31
+    The request object used to generate this response.
  32
+
  33
+``template``
  34
+    The full name of a template to use or sequence of template names.
  35
+
  36
+Optional arguments
  37
+------------------
  38
+
  39
+``dictionary``
  40
+    A dictionary of values to add to the template context. By default, this
  41
+    is an empty dictionary. If a value in the dictionary is callable, the
  42
+    view will call it just before rendering the template.
  43
+
  44
+``context_instance``
  45
+    The context instance to render the template with. By default, the template
  46
+    will be rendered with a ``RequestContext`` instance (filled with values from
  47
+    ``request`` and ```dictionary``).
  48
+
  49
+``mimetype``
  50
+    The MIME type to use for the resulting document. Defaults to the value of
  51
+    the :setting:`DEFAULT_CONTENT_TYPE` setting.
  52
+
  53
+Example
  54
+-------
  55
+
  56
+The following example renders the template ``myapp/index.html`` with the
  57
+MIME type ``application/xhtml+xml``::
  58
+
  59
+    from django.shortcuts import render_to_response
  60
+
  61
+    def my_view(request):
  62
+        # View code here...
  63
+        return render_to_response('myapp/index.html', {"foo": "bar"},
  64
+            mimetype="application/xhtml+xml")
  65
+
  66
+This example is equivalent to::
  67
+
  68
+    from django.http import HttpResponse
  69
+    from django.template import Context, loader
  70
+
  71
+    def my_view(request):
  72
+        # View code here...
  73
+        t = loader.get_template('myapp/template.html')
  74
+        c = RequestContext(request, {'foo': 'bar'})
  75
+        return HttpResponse(t.render(c),
  76
+            mimetype="application/xhtml+xml")
  77
+
  78
+
15 79
 ``render_to_response``
16 80
 ======================
17 81
 
2  tests/regressiontests/views/templates/debug/render_test.html
... ...
@@ -1 +1 @@
1  
-{{ foo }}.{{ bar }}.{{ baz }}.{{ processors }}
  1
+{{ foo }}.{{ bar }}.{{ baz }}.{{ STATIC_URL }}
1  tests/regressiontests/views/tests/__init__.py
@@ -5,5 +5,6 @@
5 5
 from generic.object_list import *
6 6
 from generic.simple import *
7 7
 from i18n import *
  8
+from shortcuts import *
8 9
 from specials import *
9 10
 from static import *
53  tests/regressiontests/views/tests/shortcuts.py
... ...
@@ -0,0 +1,53 @@
  1
+from django.conf import settings
  2
+from django.test import TestCase
  3
+
  4
+class ShortcutTests(TestCase):
  5
+    def setUp(self):
  6
+        self.old_STATIC_URL = settings.STATIC_URL
  7
+        self.old_TEMPLATE_CONTEXT_PROCESSORS = settings.TEMPLATE_CONTEXT_PROCESSORS
  8
+
  9
+        settings.STATIC_URL = '/path/to/static/media'
  10
+        settings.TEMPLATE_CONTEXT_PROCESSORS = (
  11
+            'django.core.context_processors.static'
  12
+        )
  13
+
  14
+    def tearDown(self):
  15
+        settings.STATIC_URL = self.old_STATIC_URL
  16
+        settings.TEMPLATE_CONTEXT_PROCESSORS = self.old_TEMPLATE_CONTEXT_PROCESSORS
  17
+
  18
+    def test_render_to_response(self):
  19
+        response = self.client.get('/views/shortcuts/render_to_response/')
  20
+        self.assertEquals(response.status_code, 200)
  21
+        self.assertEquals(response.content, 'FOO.BAR..\n')
  22
+        self.assertEquals(response['Content-Type'], 'text/html; charset=utf-8')
  23
+
  24
+    def test_render_to_response_with_request_context(self):
  25
+        response = self.client.get('/views/shortcuts/render_to_response/request_context/')
  26
+        self.assertEquals(response.status_code, 200)
  27
+        self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n')
  28
+        self.assertEquals(response['Content-Type'], 'text/html; charset=utf-8')
  29
+
  30
+    def test_render_to_response_with_mimetype(self):
  31
+        response = self.client.get('/views/shortcuts/render_to_response/mimetype/')
  32
+        self.assertEquals(response.status_code, 200)
  33
+        self.assertEquals(response.content, 'FOO.BAR..\n')
  34
+        self.assertEquals(response['Content-Type'], 'application/x-rendertest')
  35
+
  36
+    def test_render(self):
  37
+        response = self.client.get('/views/shortcuts/render/')
  38
+        self.assertEquals(response.status_code, 200)
  39
+        self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n')
  40
+        self.assertEquals(response['Content-Type'], 'text/html; charset=utf-8')
  41
+
  42
+    def test_render_with_base_context(self):
  43
+        response = self.client.get('/views/shortcuts/render/base_context/')
  44
+        self.assertEquals(response.status_code, 200)
  45
+        self.assertEquals(response.content, 'FOO.BAR..\n')
  46
+        self.assertEquals(response['Content-Type'], 'text/html; charset=utf-8')
  47
+
  48
+    def test_render_with_mimetype(self):
  49
+        response = self.client.get('/views/shortcuts/render/mimetype/')
  50
+        self.assertEquals(response.status_code, 200)
  51
+        self.assertEquals(response.content, 'FOO.BAR../path/to/static/media\n')
  52
+        self.assertEquals(response['Content-Type'], 'application/x-rendertest')
  53
+
8  tests/regressiontests/views/urls.py
@@ -143,6 +143,14 @@
143 143
 urlpatterns += patterns('regressiontests.views.views',
144 144
     url(r'view_exception/(?P<n>\d+)/$', 'view_exception', name='view_exception'),
145 145
     url(r'template_exception/(?P<n>\d+)/$', 'template_exception', name='template_exception'),
  146
+
  147
+    (r'^shortcuts/render_to_response/$', 'render_to_response_view'),
  148
+    (r'^shortcuts/render_to_response/request_context/$', 'render_to_response_view_with_request_context'),
  149
+    (r'^shortcuts/render_to_response/mimetype/$', 'render_to_response_view_with_mimetype'),
  150
+    (r'^shortcuts/render/$', 'render_view'),
  151
+    (r'^shortcuts/render/base_context/$', 'render_view_with_base_context'),
  152
+    (r'^shortcuts/render/mimetype/$', 'render_view_with_mimetype'),
  153
+
146 154
 )
147 155
 
148 156
 # simple generic views.
44  tests/regressiontests/views/views.py
... ...
@@ -1,11 +1,12 @@
1 1
 import sys
2 2
 
3  
-from django.http import HttpResponse, HttpResponseRedirect
4 3
 from django import forms
  4
+from django.http import HttpResponse, HttpResponseRedirect
  5
+from django.core.urlresolvers import get_resolver
  6
+from django.shortcuts import render_to_response, render
  7
+from django.template import Context, RequestContext
5 8
 from django.views.debug import technical_500_response
6 9
 from django.views.generic.create_update import create_object
7  
-from django.core.urlresolvers import get_resolver
8  
-from django.shortcuts import render_to_response
9 10
 
10 11
 from regressiontests.views import BrokenException, except_args
11 12
 
@@ -57,3 +58,40 @@ def template_exception(request, n):
57 58
     return render_to_response('debug/template_exception.html',
58 59
         {'arg': except_args[int(n)]})
59 60
 
  61
+# Some views to exercise the shortcuts
  62
+
  63
+def render_to_response_view(request):
  64
+    return render_to_response('debug/render_test.html', {
  65
+        'foo': 'FOO',
  66
+        'bar': 'BAR',
  67
+    })
  68
+
  69
+def render_to_response_view_with_request_context(request):
  70
+    return render_to_response('debug/render_test.html', {
  71
+        'foo': 'FOO',
  72
+        'bar': 'BAR',
  73
+    }, context_instance=RequestContext(request))
  74
+
  75
+def render_to_response_view_with_mimetype(request):
  76
+    return render_to_response('debug/render_test.html', {
  77
+        'foo': 'FOO',
  78
+        'bar': 'BAR',
  79
+    }, mimetype='application/x-rendertest')
  80
+
  81
+def render_view(request):
  82
+    return render(request, 'debug/render_test.html', {
  83
+        'foo': 'FOO',
  84
+        'bar': 'BAR',
  85
+    })
  86
+
  87
+def render_view_with_base_context(request):
  88
+    return render(request, 'debug/render_test.html', {
  89
+        'foo': 'FOO',
  90
+        'bar': 'BAR',
  91
+    }, context_instance=Context())
  92
+
  93
+def render_view_with_mimetype(request):
  94
+    return render(request, 'debug/render_test.html', {
  95
+        'foo': 'FOO',
  96
+        'bar': 'BAR',
  97
+    }, mimetype='application/x-rendertest')

0 notes on commit b3d2091

Please sign in to comment.
Something went wrong with that request. Please try again.