Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Django Redirects (Summary)

This wraps up this guide on HTTP redirects with Django. Congratulations: you have now touched on every aspect of redirects all the way from the low-level details of the HTTP protocol to the high-level way of dealing with them in Django.

You learned how an HTTP redirect looks under the hood, what the different status codes are, and how permanent and temporary redirects differ. This knowledge is not specific to Django and is valuable for web development in any language.

You can now perform a redirect with Django, either by using the redirect response classes HttpResponseRedirect and HttpResponsePermanentRedirect, or with the convenience function django.shortcuts.redirect(). You saw solutions for a couple of advanced use cases and know how to steer clear of common pitfalls.

Here are resources for more information on Django redirects and HTTP redirects:


Sample Code (.zip)

30.3 KB

Course Slides (.pdf)

3.3 MB

00:00 I’m glad you’ve made it this far. In the first lesson, I showed you what an HTTP redirect was and how it worked. Then, I showed you the redirect() shortcut.

00:09 I followed that up with the RedirectView class helper. In the previous lesson, I spoke about parameters and how to use query strings with redirects.

00:18 In this final lesson, I’m going to wrap things up and show you a few problem areas that you need to be careful with. First off, remember that redirect() isn’t a command.

00:27 It doesn’t directly call the view. It returns an HTTP response to the browser. It’s the browser that does the work of coming back. It’s easy to introduce bugs if you forget this fact. For example, let’s say you have a product_view() that looks up a Product, and if the product does not exist, does a redirect to '/'. So far, so good.

00:51 Then, someone comes along and refactors it. Because you’re likely to do this in multiple views, it’s put into a helper function called get_product_or_redirect().

01:00 Can you see the bug? In the first case, get_product_or_redirect() returns a Product. In the second, it returns an HttpResponse. The product_view() expects it to be a Product, and then renders it.

01:15 This means the redirect won’t happen. product_detail.html will get rendered either way, and in the second case, with the product variable containing an HttpResponse object, not a Product.

01:29 Another thing to be careful with is redirect loops. A loop can happen if two or more methods redirect back to each other. This is a very simple example. The first view redirects to the second and the second redirects to the first.

01:43 The browser will look like it’s hung. It will just constantly go back and forth hitting this and not showing anything to the user. The previous example is probably not going to happen.

01:53 You’ll likely see it inside of your code, or it might pop up only if you’re refactoring and you catch it during testing. This example’s a little more subtle.

02:03 The first view I have here looks for featured products. It searches for products that have featured set to True. If there’s only 1 of them, it redirects to that product’s product_view().

02:15 Otherwise, it shows the featured product list.

02:19 The product_view() itself looks up a product, which—if it was redirected from featured_products_views()—will be the single featured product, and if it doesn’t exist, redirects to the featured_products_views().

02:32 This is where the tricky part happens. Notice that this lookup only happens if in_stock=True. There’s a situation here where a product is featured, but it’s sold out.

02:44 If there’s only one featured product and it’s sold out, the featured_products_view() will redirect to product_view(), it won’t be found because it’s not in stock and it will redirect back to featured_products_views().

02:56 You have a loop.

02:59 The last caveat I want to talk about is permanent redirects. As their name implies, they’re permanent. By permanent, I mean the browser will never again try the original URL.

03:11 It stores the original URL, and if you type it in, it will automatically go to the permanent redirect without going to the server. Generally, this is a good thing—until someone changes their mind.

03:22 Let me run you through an example. Let’s say marketing decides to reorganize the site and combine the announcements section with the blog section. To keep your SEO nice and healthy, you permanently redirect the announcements section.

03:36 Then, marketing goes and changes their mind again. Well, you can no longer use your original announcements URL. Anyone who had visited it before will not be able to reach it again unless they empty their cache.

03:49 This can particularly bite you in the local development environment. Oftentimes, you run the development server on localhost. If one of your projects has a 301 in it, your browser will cache this and associate it with the local IP.

04:03 If another project then tries to use the same URL, your browser will use the cached redirect. This might result in a 404 because the new project might not have a page with the same name as the redirect.

04:16 It might even be worse if it actually had it. This can lead to some head-scratching moments. One way around this is to modify your hosts file with clientA.example.com associated with localhost. If you get a redirect from clientA, it will only apply to clientA. I like to do this when I’m developing, not just because of this situation, but also because some browsers behave a little oddly when storing things like names and passwords with the local IP. By having an example URL, you’ll always behave closer to the real world.

04:49 example.com is actually not a valid domain name, so you can always safely use it. For more information, you can dig into the Django docs. There’s plenty of information on the HttpResponseRedirect object, the redirect() shortcut, and the RedirectView.

05:07 If specifications are your thing, you can dig into the RFC that talks about the 300 codes, or the Common Weakness Enumeration site has an excellent article on URL redirection to untrusted sites, or the parameterized URL redirect that I showed you earlier—also known as an open redirect.

05:25 Thanks for your attention. I hope you’ve enjoyed the content.

Become a Member to join the conversation.