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

Unlock This Lesson

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

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Introduction to HTTP Redirects

In this lesson, you’ll learn the answer to the obvious question: what’s an HTTP redirect? This is a response from the webserver that tells your browser that a page has been moved. In addition to telling the browser that the page has been moved, it usually indicates where to. Most browsers automatically load the new location.

The sample code for this course was tested in Django 3 with Python 3.8. The code should be backwards compatible with Django 2.

Here are resources for more information on Django views and URL patterns:

00:00 So, let’s get started! The obvious question: what’s an HTTP redirect? This is a response from the webserver that tells your browser that a page has been moved. In addition to telling the browser that the page has been moved, it usually indicates where to. Most browsers automatically load the new location.

00:18 This means users may not even realize that the redirect has happened. There are several different kinds of redirects, and how the browser caches the response dictates the behavior when the URL is visited again.

00:30 This means you may want to be careful about which kind of redirect you use. So, why would you want to redirect? Let’s start answering that question by looking at how Django itself uses redirects.

00:41 If you try to access a URL that is in a area that requires authentication, and you haven’t authenticated yet, Django will redirect you to the login page.

00:51 Likewise, once you’ve completed that login, it will redirect you back to the URL you came from. If you’re changing your password, it will redirect you to the Successfully Changed password page, after the password change has been input. And in the Django admin, if you’ve created a new object, it will send you to the object listing, afterwards.

01:12 Outside of Django, URL shorteners like bit.ly are, essentially, redirect engines. It’s also an important part of form handling. A common pattern in Django is to use a single view for both presenting the form and accepting its submission. Inside the view, you check whether it is a GET or a POST. If it is a GET, the form is presented to the user.

01:33 If it is a POST, the form is processed for input. If you use this mechanism, you need to be able to send the user to a subsequent page, after the form has been processed successfully. Redirects allow you to do this.

01:49 Let’s take a look at what happens when I hit a Django webserver. I’m going to use curl to hit the development server, hitting the name hello.

01:58 The 'hello/' path is found inside of the destination app urls file, and maps to a view called hello_world in destination.views.

02:08 You can see that code here. The hello_world() view returns an HttpResponse object using a content_type='text/plain', meaning just the string "Hello World\n" gets returned to the web browser—no wrapper HTML. Throughout this course, I’m going to use content_type='text/plain' to make it easier to see what the results are, rather than having the additional complexity of the wrapped HTML.

02:33 This view returns, curl gets the body back, and you see Hello World printed to the screen. Let’s try that again. This time using curl’s --include parameter.

02:46 --include tells curl to print out the headers as well as the body coming back. You can see the response code of 200 coming back from the webserver, six additional headers, as well as the Hello World body.

03:01 Let’s do that again, this time hitting a URL that redirects. Once again, using curl’s --include, this time going to a URL called /redirect/.

03:11 The 'redirect/' pattern is found in the simple app urls file. You can see it here: 'redirect/' goes to views.redirect_view.

03:21 Inside of simple.views, you can see that the redirect_view() is using the redirect() shortcut going to '/destination/'.

03:30 This response is returned by Django to curl. It’s important to understand that Django is not actually sending you somewhere else. It’s sending a message to the browser to go somewhere else.

03:43 It is the browser’s responsibility to go to the new URL.

03:48 You can see the response here. Status code 302 means redirect. The Location header sees /destination/ telling the browser where to go.

03:59 By default, curl does not follow redirects. It just prints out the information. If I’d been using Chrome or Firefox to show this demo, you wouldn’t see this.

04:08 You would just see the results of /destination. By default, Chrome and Firefox follow through on the Location.

04:17 Every response from the webserver includes a status code. You’ve seen the 200, meaning success, in the previous examples with curl.

04:24 In addition to that, you may have come across others, as well. 401 means Unauthorized and causes the browser to pop up an authentication box. 403 tells the user they don’t have permission to see this URL. 404 means the page isn’t found.

04:40 And 500 means you’ve messed up as the programmer on the server side. Going through the example with curl, I showed you the 302 redirect status.

04:49 There are a series of redirect status codes, starting with 301, meaning Moved Permanently. 302 was the one that I showed you. In the original specification, it meant Moved Temporarily. In HTTP 1.1, it was changed to mean Found. 1.1 also introduced the concept of 303 and 307.

05:11 This is one of those cases where the standards and the real world don’t really match. Although HTTP 1.1 and on have several different ways of using these redirects, with subtle differences about how to behave in the cases of GETs and POSTs, most programmers still use 302 under its original intent Moved Temporarily.

05:31 Here’s the actual spec.

05:34 “The 302 (Found) status code indicates that the target resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client ought to continue to use the effect of request URI for future requests.

05:48 The server SHOULD generate a Location header field in the response containing a URI reference for the different URI. The user agent MAY use the Location field value for automatic redirection.” Why is it that specifications always sound like the legalese at the end of a drug commercial?

06:04 What this essentially says is the 302 will include a Location header field containing the value of the new URL. It’s up to the implementation of the browser to decide whether or not to automatically redirect. It also states that in subsequent visits to this original URL, the browser should still hit the original URL as it may no longer be redirected, or it may be redirected somewhere else. This is an important distinction.

06:29 There’s both temporary and permanent redirects. In the case of temporary redirects, the browser should not store this information. Every time the original URL is hit, the browser should attempt to go to that URL. For permanent redirects, the browser’s meant to remember the redirection. Subsequent typing in of the original URL should automatically go to the redirected URL.

06:52 This means you can’t change your mind about a 301. I’ll talk more about this in Lesson 5.

06:58 That’s the basics of HTTP Redirect. Next up, I’ll talk about Django’s shortcut redirect() method.

Become a Member to join the conversation.