162

How do I accomplish a simple redirect (e.g. cflocation in ColdFusion, or header(location:http://) for PHP) in Django?

Kyle Hayes
  • 5,225
  • 8
  • 38
  • 53

10 Answers10

256

It's simple:

from django.http import HttpResponseRedirect

def myview(request):
    ...
    return HttpResponseRedirect("/path/")

More info in the official Django docs

Update: Django 1.0

There is apparently a better way of doing this in Django now using generic views.

Example -

from django.views.generic.simple import redirect_to

urlpatterns = patterns('',   
    (r'^one/$', redirect_to, {'url': '/another/'}),

    #etc...
)

There is more in the generic views documentation. Credit - Carles Barrobés.

Update #2: Django 1.3+

In Django 1.5 redirect_to no longer exists and has been replaced by RedirectView. Credit to Yonatan

from django.views.generic import RedirectView

urlpatterns = patterns('',
    (r'^one/$', RedirectView.as_view(url='/another/')),
)
Community
  • 1
  • 1
Baishampayan Ghose
  • 19,928
  • 10
  • 56
  • 60
  • 8
    This is no longer the best method as of Django 1.0. See this answer: http://stackoverflow.com/questions/523356/python-django-page-redirect/3841632#3841632 – Jake Dec 16 '10 at 00:40
  • 2
    Why not using `redirect` from `django.shortcuts`? – Afshin Mehrabani Oct 05 '12 at 07:42
  • 4
    I use `('^pattern/$', lambda x: redirect('/redirect/url/'))` – mrmagooey Dec 21 '12 at 01:56
  • 5
    This is already deprecated starting in Django 1.5. Use 'RedirectView' instead: https://docs.djangoproject.com/en/1.5/ref/class-based-views/base/#redirectview – Yonatan Apr 29 '13 at 23:42
  • Its actually not deprecated, what are you saying is deprecated? redirect ? Using this method I don't know how to pass the value of parameters to lambda, i.e. url(r'^(?P\d+)/$', lambda x: HttpResponseRedirect(reverse('dailyreport_location', args=['%(location_id)', ]))) does not work – radtek Jun 12 '14 at 16:51
  • Thanks for `HttpResponseRedirect` – Pratibha Feb 27 '18 at 05:45
114

Depending on what you want (i.e. if you do not want to do any additional pre-processing), it is simpler to just use Django's redirect_to generic view:

from django.views.generic.simple import redirect_to

urlpatterns = patterns('',
    (r'^one/$', redirect_to, {'url': '/another/'}),

    #etc...
)

See documentation for more advanced examples.


For Django 1.3+ use:

from django.views.generic import RedirectView

urlpatterns = patterns('',
    (r'^one/$', RedirectView.as_view(url='/another/')),
)
the
  • 21,007
  • 11
  • 68
  • 101
Carles Barrobés
  • 11,608
  • 5
  • 46
  • 60
  • +1 for using a generic view rather than implementing your own (no matter how simple) as in the (current) top voted answer. – Day Dec 16 '10 at 00:33
  • Does anyone have any examples for if you *do* want to do additional pre-processing? – eageranalyst Jun 04 '11 at 12:34
  • 1
    Then I'd suggest either write a custom view that does the processing and then calls the generic view, or write a decorator e.g. pre_process and decorate the generic view: (r'^one/$', pre_process(redirect_to), {'url': '/another/'}) – Carles Barrobés Jun 06 '11 at 09:35
  • 1
    @niallsco: if you want to do additional processing, then it's best to use the redirect shortcut as described by Kennu in [here](http://stackoverflow.com/questions/523356/python-django-page-redirect/3645846#3645846) – Lie Ryan Jul 21 '11 at 03:45
  • 1
    In django 1.4, importing redirect_to gives a depracation warning. – joctee May 08 '12 at 11:21
38

There's actually a simpler way than having a view for each redirect - you can do it directly in urls.py:

from django.http import HttpResponsePermanentRedirect

urlpatterns = patterns(
    '',
    # ...normal patterns here...
    (r'^bad-old-link\.php',
     lambda request: HttpResponsePermanentRedirect('/nice-link')),
)

A target can be a callable as well as a string, which is what I'm using here.

Teddy
  • 6,013
  • 3
  • 26
  • 38
  • 2
    True, but using the `redirect_to` generic view that comes with django is simpler still and more readable. See Carles answer http://stackoverflow.com/questions/523356/python-django-page-redirect/3841632#3841632 – Day Dec 16 '10 at 00:36
28

Since Django 1.1, you can also use the simpler redirect shortcut:

from django.shortcuts import redirect

def myview(request):
    return redirect('/path')

It also takes an optional permanent=True keyword argument.

Kennu
  • 1,093
  • 9
  • 13
14

If you want to redirect a whole subfolder, the url argument in RedirectView is actually interpolated, so you can do something like this in urls.py:

from django.conf.urls.defaults import url
from django.views.generic import RedirectView

urlpatterns = [
    url(r'^old/(?P<path>.*)$', RedirectView.as_view(url='/new_path/%(path)s')),
]

The ?P<path> you capture will be fed into RedirectView. This captured variable will then be replaced in the url argument you gave, giving us /new_path/yay/mypath if your original path was /old/yay/mypath.

You can also do ….as_view(url='…', query_string=True) if you want to copy the query string over as well.

odinho - Velmont
  • 20,922
  • 6
  • 41
  • 33
10

With Django version 1.3, the class based approach is:

from django.conf.urls.defaults import patterns, url
from django.views.generic import RedirectView

urlpatterns = patterns('',
    url(r'^some-url/$', RedirectView.as_view(url='/redirect-url/'), name='some_redirect'),
)

This example lives in in urls.py

Zlatko
  • 111
  • 2
  • 6
6

Beware. I did this on a development server and wanted to change it later.

I had to clear my caches to change it. In order to avoid this head-scratching in the future, I was able to make it temporary like so:

from django.views.generic import RedirectView

url(r'^source$', RedirectView.as_view(permanent=False, 
                                      url='/dest/')),
Community
  • 1
  • 1
Gringo Suave
  • 29,931
  • 6
  • 88
  • 75
2

page_path = define in urls.py

def deletePolls(request):
    pollId = deletePool(request.GET['id'])
    return HttpResponseRedirect("/page_path/")
Moddasir
  • 1,449
  • 13
  • 33
1

You can do this in the Admin section. It's explained in the documentation.

https://docs.djangoproject.com/en/dev/ref/contrib/redirects/

mcneo
  • 189
  • 5
0

This should work in most versions of django, I am using it in 1.6.5:

from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
urlpatterns = patterns('',
    ....
    url(r'^(?P<location_id>\d+)/$', lambda x, location_id: HttpResponseRedirect(reverse('dailyreport_location', args=[location_id])), name='location_stats_redirect'),
    ....
)

You can still use the name of the url pattern instead of a hard coded url with this solution. The location_id parameter from the url is passed down to the lambda function.

radtek
  • 34,210
  • 11
  • 144
  • 111