Django Redirects (Updated)
Update: A reader has kindly pointed out to me that django.contrib.redirects already exists, which does what I describe below! D'oh. I'm sure that wasn't there when I last looked. Don't use my code - use the Django one, of course. Consider this... another talked-through example of middleware. And a lesson in reading before you write.
There are loads of ways to tell your audience that their content has HTTP 301: Moved Permanently. A line in your Apache/lighttpd/whatever configuration perhaps; or you could even wire in Django's redirect_to generic view in your urls.py file. These are the recommended approaches: directly configuring your web server is likely to be the most performant solution (as requests will never touch your app server cluster), and the urls.py method will even let you pick apart the incoming URL and plug arguments into the URL to be redirected to. All good stuff.
Sometimes, however, you need to get a redirect up NOW. Perhaps a high-profile site has linked to an article of yours, but they've messed up the link, and it's 2am and you're in the UK and all your techs who would normally do this for you are in bed (or the pub) and all that potential advertising revenue is bouncing off your 404 page.
Here's a tiny app (based heavily on flatpages) that lets you quickly and easily add a redirect to your site. You can download it from the Software section. Here's how you install it:
- Unpack the file and drop it somewhere in your PYTHONPATH, so Django can import it.
- Edit your settings file, and add 'stereoplex.flatredirects' to your INSTALLED_APPS
- While you're add it, add 'stereoplex.flatredirects.middleware.FlatredirectFallbackMiddleware' to your MIDDLEWARE_CLASSES
- Resync your database, and you should be good to go.
It's pretty simple to use. You should see the 'Flatredirects' application appear in your admin interface, and it'll let you add Redirect objects.
Your 'from url' should be the location which is currently 404'ing (ie. the incoming, broken link). It works in the same way as flatpages - so it's relative to the root of your site, and it should have a leading and trailing slash.
The 'to url' is sent back to the browser - it can be relative, or absolute.
Once you've saved that, try it - you should find that going to yoursite.com/redirectfrom (where redirectfrom is what you put in the 'from url' box) will now redirect you appropriately.
How does it work?
Flatredirects uses a very simple Django middleware (not to be confused with WSGI middleware) to do its work. I've talked about Django middleware in a previous post. In that example, I implemented a process_request() middleware, since I needed to augment the request before it was passed on to.
This time, we're dealing with the response, so we provide a process_response() method. Take a look at the files middleware.py and views.py in stereoplex/flatredirects.
The logic is pretty simple: if the response is going to be a 404, then hand processing off to the flatredirect view. This view looks the URL up in the database, and uses Django's own redirect_to generic view to perform the redirection if there is a match. If there isn't, 404 is raised once more back to the middleware; and in this case, the middleware returns the original 404.
Is this suitable for doing all your redirects?
This product makes adding redirects very easy. However, there are some caveats to this approach:
- In this implementation at least, there's no ability to dynamically generate the redirect URL.
- More importantly, you should consider the performance implications of all your potential 404 accesses causing a database hit.
So it's probably OK as a quick band-aid if nobody's around to fiddle with your web server configuration - but don't blame me if your database melts!
Note that this is an alpha release, but feel free to let me know of any bugs, or features that you'd like to see.
Get it at:
I've disabled comments for now due to spam problems - I'll turn them back on when I've fixed it!