diff --git a/django/views/generic/simple.py b/django/views/generic/simple.py index 0a68b82a106ce..3b5309df96862 100644 --- a/django/views/generic/simple.py +++ b/django/views/generic/simple.py @@ -1,5 +1,5 @@ from django.template import loader, RequestContext -from django.http import HttpResponse, HttpResponsePermanentRedirect, HttpResponseGone +from django.http import HttpResponse, HttpResponseRedirect, HttpResponsePermanentRedirect, HttpResponseGone def direct_to_template(request, template, extra_context=None, mimetype=None, **kwargs): """ @@ -17,7 +17,7 @@ def direct_to_template(request, template, extra_context=None, mimetype=None, **k t = loader.get_template(template) return HttpResponse(t.render(c), mimetype=mimetype) -def redirect_to(request, url, **kwargs): +def redirect_to(request, url, permanent=True, **kwargs): """ Redirect to a given URL. @@ -30,8 +30,12 @@ def redirect_to(request, url, **kwargs): ) If the given url is ``None``, a HttpResponseGone (410) will be issued. + + If the ``permanent`` argument is False, then the response will have a 302 + HTTP status code. Otherwise, the status code will be 301. """ if url is not None: - return HttpResponsePermanentRedirect(url % kwargs) + klass = permanent and HttpResponsePermanentRedirect or HttpResponseRedirect + return klass(url % kwargs) else: return HttpResponseGone() diff --git a/docs/ref/generic-views.txt b/docs/ref/generic-views.txt index c14cc295d2309..efa49e3ee3781 100644 --- a/docs/ref/generic-views.txt +++ b/docs/ref/generic-views.txt @@ -129,14 +129,29 @@ If the given URL is ``None``, Django will return an ``HttpResponseGone`` (410). * ``url``: The URL to redirect to, as a string. Or ``None`` to raise a 410 (Gone) HTTP error. +**Optional arguments:** + + * ``permanent``: Whether the redirect should be permanent. The only + difference here is the HTTP status code returned. If ``True``, then the + redirect will use status code 301. If ``False``, then the redirect will + use status code 302. By default, ``permanent`` is ``True``. + **Example:** -This example redirects from ``/foo//`` to ``/bar//``:: +This example issues a permanent redirect (HTTP status code 301) from +``/foo//`` to ``/bar//``:: urlpatterns = patterns('django.views.generic.simple', ('^foo/(?P\d+)/$', 'redirect_to', {'url': '/bar/%(id)s/'}), ) +This example issues a non-permanent redirect (HTTP status code 302) from +``/foo//`` to ``/bar//``:: + + urlpatterns = patterns('django.views.generic.simple', + ('^foo/(?P\d+)/$', 'redirect_to', {'url': '/bar/%(id)s/', 'permanent': False}), + ) + This example returns a 410 HTTP error for requests to ``/bar/``:: urlpatterns = patterns('django.views.generic.simple', diff --git a/tests/modeltests/test_client/models.py b/tests/modeltests/test_client/models.py index 2cca618b4ef7a..b975d139c658f 100644 --- a/tests/modeltests/test_client/models.py +++ b/tests/modeltests/test_client/models.py @@ -118,6 +118,12 @@ def test_permanent_redirect(self): # Check that the response was a 301 (permanent redirect) with absolute URI self.assertRedirects(response, 'http://django.testserver/test_client/get_view/', status_code=301) + def test_temporary_redirect(self): + "GET a URL that does a non-permanent redirect" + response = self.client.get('/test_client/temporary_redirect_view/') + # Check that the response was a 302 (non-permanent redirect) + self.assertRedirects(response, 'http://testserver/test_client/get_view/', status_code=302) + def test_redirect_to_strange_location(self): "GET a URL that redirects to a non-200 page" response = self.client.get('/test_client/double_redirect_view/') diff --git a/tests/modeltests/test_client/urls.py b/tests/modeltests/test_client/urls.py index 0e511d7360b39..3c84a768a0a0a 100644 --- a/tests/modeltests/test_client/urls.py +++ b/tests/modeltests/test_client/urls.py @@ -8,7 +8,8 @@ (r'^header_view/$', views.view_with_header), (r'^raw_post_view/$', views.raw_post_view), (r'^redirect_view/$', views.redirect_view), - (r'^permanent_redirect_view/$', redirect_to, { 'url': '/test_client/get_view/' }), + (r'^permanent_redirect_view/$', redirect_to, {'url': '/test_client/get_view/'}), + (r'^temporary_redirect_view/$', redirect_to, {'url': '/test_client/get_view/', 'permanent': False}), (r'^double_redirect_view/$', views.double_redirect_view), (r'^bad_view/$', views.bad_view), (r'^form_view/$', views.form_view),