Parameters and Redirects
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.
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() displays a number to the screen by spitting it out in an
show_random_number() randomly chooses a number between
5, and then redirects to
Let me walk you through this by hitting it with
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
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
This is then redirected. The end result is a
Location header with the redirect to the
show_number() view with a parameter of
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.
The user is sent to the login page, and that login page redirect is parameterized with a value called
next parameter contains where to send the user after successful authentication.
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.
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.
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 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.
So that’s how to parameterize a redirect. What if instead, you want to redirect using a different status code?
HttpPermanentRedirectResponse are built-in, returning
302, respectively. If you wish to use one of the newer redirect codes, they’re not built into Django.
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.
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.
Hi, redirect is a shortcut to HttpResponseRedirect or HttpResponsePermanentRedirect. When should we use the shortcut rather than the classes themselves?
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.
robertkulinski93 on Sept. 13, 2020
params/views.py is missing import