127

How can I redirect traffic that doesn't match any of my other URLs back to the home page?

urls.py:

urlpatterns = patterns('',
    url(r'^$', 'macmonster.views.home'),
    #url(r'^macmon_home$', 'macmonster.views.home'),
    url(r'^macmon_output/$', 'macmonster.views.output'),
    url(r'^macmon_about/$', 'macmonster.views.about'),
    url(r'^.*$',  'macmonster.views.home'),
)

As it stands, the last entry sends all "other" traffic to the home page but I want to redirect via either an HTTP 301 or 302.

daaawx
  • 3,273
  • 2
  • 17
  • 16
felix001
  • 15,341
  • 32
  • 94
  • 121

5 Answers5

220

You can try the Class Based View called RedirectView

from django.views.generic.base import RedirectView

urlpatterns = patterns('',
    url(r'^$', 'macmonster.views.home'),
    #url(r'^macmon_home$', 'macmonster.views.home'),
    url(r'^macmon_output/$', 'macmonster.views.output'),
    url(r'^macmon_about/$', 'macmonster.views.about'),
    url(r'^.*$', RedirectView.as_view(url='<url_to_home_view>', permanent=False), name='index')
)

Notice how as url in the <url_to_home_view> you need to actually specify the url.

permanent=False will return HTTP 302, while permanent=True will return HTTP 301.

Alternatively you can use django.shortcuts.redirect

Update for Django 2+ versions

With Django 2+, url() is deprecated and replaced by re_path(). Usage is exactly the same as url() with regular expressions. For replacements without the need of regular expression, use path().

from django.urls import re_path

re_path(r'^.*$', RedirectView.as_view(url='<url_to_home_view>', permanent=False), name='index')
Dakota
  • 2,915
  • 2
  • 28
  • 25
dmg
  • 7,438
  • 2
  • 24
  • 33
  • i added this but just got a HTTP 500 error ? url(r'^.*$', RedirectView.as_view(url='macmon_about', permanent=False) – felix001 Feb 19 '13 at 18:01
  • 1
    You seem to be missing a ")", side scroll to the end and you'll see it. You can omit the `name` part though – dmg Feb 19 '13 at 18:05
  • 1
    @felix001 btw, HTTP 500 usually (as in 99% of the times) means you have a syntax error, take a look at this - https://docs.djangoproject.com/en/dev/howto/error-reporting/#server-errors. When a site is under development it is always good to have `DEBUG = True` or at least set the `ADMINS` option - https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-ADMINS – dmg Feb 21 '13 at 09:59
  • HOW to do i pass slug and use that field to create redirection url. EXA : url( r'^(?P[a-zA-Z0-9-]+)/', RedirectView.as_view(url='http://'+slug+'.mywebsite.com', permanent=False),) – Roshan Jan 22 '14 at 10:26
  • Note that using this method it is real easy to get the user caught in a redirect loop. – smilebomb Jun 11 '14 at 17:44
  • A better match is just ^, which matches the beginning of a string. `url(r'^', ...)` – Kurt Sep 27 '14 at 05:04
  • A note, be sure to test your redirect before making it permanent. Once its permanent its a pain in the butt to clear the entry from the end user's browser. – ThorSummoner Nov 30 '14 at 00:37
  • I think it's also worth mentioning that you can use `reverse_lazy` in the `url` parameter, if you don't want to hardcode the url that it redirects to. https://docs.djangoproject.com/en/1.7/ref/urlresolvers/#reverse-lazy – davegaeddert Mar 31 '15 at 19:31
  • 5 years later using the pattern_name parameter to as_view() is probably a better choice, as mentioned by @Rexford below. – Andreas Bergström Mar 14 '18 at 15:29
  • Perfect answer ! Thanks – Sunny Chaudhari Mar 18 '20 at 13:25
40

In Django 1.8, this is how I did mine.

from django.views.generic.base import RedirectView

url(r'^$', views.comingSoon, name='homepage'),
# whatever urls you might have in here
# make sure the 'catch-all' url is placed last
url(r'^.*$', RedirectView.as_view(pattern_name='homepage', permanent=False))

Instead of using url, you can use the pattern_name, which is a bit un-DRY, and will ensure you change your url, you don't have to change the redirect too.

mohlman3
  • 311
  • 3
  • 7
KhoPhi
  • 9,660
  • 17
  • 77
  • 128
21

The other methods work fine, but you can also use the good old django.shortcut.redirect.

The code below was taken from this answer.

In Django 2.x:

from django.shortcuts import redirect
from django.urls import path, include

urlpatterns = [
    # this example uses named URL 'hola-home' from app named hola
    # for more redirect's usage options: https://docs.djangoproject.com/en/2.1/topics/http/shortcuts/
    path('', lambda request: redirect('hola/', permanent=True)),
    path('hola/', include('hola.urls')),
]
EMiDU
  • 654
  • 1
  • 7
  • 24
12

If you are stuck on django 1.2 like I am and RedirectView doesn't exist, another route-centric way to add the redirect mapping is using:

(r'^match_rules/$', 'django.views.generic.simple.redirect_to', {'url': '/new_url'}),  

You can also re-route everything on a match. This is useful when changing the folder of an app but wanting to preserve bookmarks:

(r'^match_folder/(?P<path>.*)', 'django.views.generic.simple.redirect_to', {'url': '/new_folder/%(path)s'}),  

This is preferable to django.shortcuts.redirect if you are only trying to modify your url routing and do not have access to .htaccess, etc (I'm on Appengine and app.yaml doesn't allow url redirection at that level like an .htaccess).

Blaine Garrett
  • 1,286
  • 15
  • 23
  • 5
    This old format is deprecated or removed in new versions of Django, but you can still use url keywords when redirecting using RedirectView as described in the accepted answer. Example: `(r'^match_folder/(?P.*)/$', RedirectView.as_view(url='/new_folder/%(path)s/', permanent=True), name='view-name'),` – Micah Walter May 30 '18 at 20:34
9

Another way of doing it is using HttpResponsePermanentRedirect like so:

In view.py

def url_redirect(request):
    return HttpResponsePermanentRedirect("/new_url/")

In the url.py

url(r'^old_url/$', "website.views.url_redirect", name="url-redirect"),
sirFunkenstine
  • 8,135
  • 6
  • 40
  • 57