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

Unlock This Lesson

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

Unlock This Lesson

Parameters and Redirects

00:00 In the previous lesson, I talked about the RedirectView class helper. In this lesson, I’m going to talk about parameterizing your redirects.

00:08 Sometimes you need to pass parameters along with your redirected URL. This can be done with a query string, just like any other URL.

00:17 Let me demonstrate that with these two views. The first view from lines 8 through 14 is show_random_number(), and the second view, which is 16 through 18, is show_number().

00:30 show_number() displays a number to the screen by spitting it out in an HttpResponse object. show_random_number() randomly chooses a number between 1 and 5, and then redirects to show_number().

00:43 Let me walk you through this by hitting it with curl.

00:53 You’ll need a parameterized query string. You can do that by URL encoding a dictionary. Line 9 creates that dictionary with the keyword "number" and using Python’s choice() method from the random library to randomly choose a number between 1 and 5. Line 11 looks up the URL that you’re going to redirect to, line 12 turns the dictionary into a query string, and line 13 marries the base_url from the lookup with a ? and the resulting query_string.

01:27 This is then redirected. The end result is a Location header with the redirect to the show_number() view with a parameter of number=3.

01:39 Django itself uses this methodology to deal with login redirects. The @login_required decorator allows you to wrap a view and redirect the user if they hit the URL and aren’t currently authenticated.

01:53 The user is sent to the login page, and that login page redirect is parameterized with a value called next. That next parameter contains where to send the user after successful authentication.

02:06 Here’s an example. Let’s say your view was product_edit() and required the user to log in. When the user hits this URL, they’re sent to the admin login with next set to the original URL they used.

02:22 This is all great and convenient for the user, but you have to remember, this is still a URL that’s going to the browser, which means your user could tamper with it, so you have to be very careful.

02:33 Whatever is in that next URL is where the user will be sent. So if you’re writing code like this yourself, you want to make sure that the destination is safe. Fortunately, the writers of Django have thought about this. @login_required already checks that URL.

02:49 You can take advantage of their code and check it yourself using one of their internal methods. This internal method checks that a URL is relative, that it’s in an allowed list of hosts, and has a valid scheme—i.e. a scheme matching where they came from.

03:03 If they came in on HTTPS, they can only be redirected to HTTPS. In Django 2, this internal method is called is_safe_url() and is found in django.utils.http.

03:16 Django 3 has deprecated this method and replaced it with url_has_allowed_host_and_scheme(). The Django project felt is_safe_url() was a little bit misleading.

03:27 There are other ways of making a URL unsafe, so they renamed it to exactly what it does. One final word of caution: both of these are internal methods. They are not documented.

03:37 They will do what you want and the code is there, but they may not be there in the next version.

03:43 So that’s how to parameterize a redirect. What if instead, you want to redirect using a different status code? HttpRedirectResponse and HttpPermanentRedirectResponse are built-in, returning 301 and 302, respectively. If you wish to use one of the newer redirect codes, they’re not built into Django.

04:03 This can easily be worked around, though. You can override the HttpResponseRedirectBase, and set the status_code to something new, creating your own class.

04:12 Or you can just do this directly inside of your view.

04:17 Next up, I’ll wrap it up and show you a few things you want to be careful with.

Avatar image for robertkulinski93

robertkulinski93 on Sept. 13, 2020

params/ is missing import

from django.shortcuts import redirect
Avatar image for Christopher Trudeau

Christopher Trudeau RP Team on Sept. 14, 2020

Hi Robert,

Good catch. Thanks for that. There is also a syntax error in string in the HttpResponse. Obviously not one of my better days :)

The sample code will be updated shortly. A fix to the video will follow.

Avatar image for Philippe Bazard

Philippe Bazard on Nov. 23, 2020

Hi, redirect is a shortcut to HttpResponseRedirect or HttpResponsePermanentRedirect. When should we use the shortcut rather than the classes themselves?

Avatar image for Christopher Trudeau

Christopher Trudeau RP Team on Nov. 24, 2020

The objects are dumb, you have to give them a URL that is the location being redirected. The shortcut function allows you to do all sorts of useful things like looking up a named URL or pointing it directly at a view. The shortcut truly saves several lines of code for each use.

The only time I would explicitly use one of the objects is if I need to change an HTTP header that goes with the object. Even then, I’m likely to use the shortcut and then modify the object that returns from it before returning the result from the view.

Become a Member to join the conversation.