Fixed #12816 -- Added a render() shortcut.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@15008 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
d4ef841495
commit
b3d2091681
|
@ -4,7 +4,7 @@ of MVC. In other words, these functions/classes introduce controlled coupling
|
|||
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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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``
|
||||
======================
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
{{ foo }}.{{ bar }}.{{ baz }}.{{ processors }}
|
||||
{{ foo }}.{{ bar }}.{{ baz }}.{{ STATIC_URL }}
|
||||
|
|
|
@ -5,5 +5,6 @@ from generic.date_based import *
|
|||
from generic.object_list import *
|
||||
from generic.simple import *
|
||||
from i18n import *
|
||||
from shortcuts import *
|
||||
from specials import *
|
||||
from static import *
|
||||
|
|
|
@ -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')
|
||||
|
|
@ -143,6 +143,14 @@ urlpatterns += patterns('django.views.generic.simple',
|
|||
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.
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in New Issue