Restricting Views to Admin and Staff
Here are additional resources about Python lambda functions and Django user_passes_test:
00:00 Restricting Views to Admin and Staff. You’ve now written a Django view with authorization. But authorization could be more complicated than simply checking whether a user is authenticated. Django has three roles out of the box: user, staff, and superuser.
00:21
The private_place()
view seen previously uses the @login_required
decorator to see if the user is authenticated and if their account is active.
00:30
You can also authorize based on the three roles. To experiment with this feature, you’re going to need a few more user accounts. Go to the admin area at the URL seen onscreen, click the Add button next to the Users object link, and use this screen to add a new user with a username bob
.
00:54 Out-of-the-box Django now enforces password requirements. You’ll need to use both letters and numbers in any password you create.
01:03
Once you create the user, you’ll automatically be sent to the edit user page, where you can specify further details. But the defaults are good enough for bob
. Scroll to the bottom and click Save and add another. Once again, you’ll be prompted to create a user. This time, create sylvia
.
01:22 When prompted for more of Sylvia’s details, scroll down to the Permissions section and check the Staff status checkbox. With the staff attribute set, you can scroll down and save this account.
01:36
You should be able to log into the admin area using either the superuser
or sylvia
accounts. As staff, you can get into the admin area, but you won’t be able to see anything by default. You don’t have permission.
01:52
You now have a regular user, a staff member, and a superuser. Using these three accounts, try visiting /admin/
, /private_place/
, and /user_info/
to see the differences.
02:35
The @login_required
decorator is all or nothing: you’re either logged in or you’re not. Django also has the @user_passes_test
decorator.
02:44
This decorator allows you to specify a check that allows the user in if passed. Try adding this view to core/views.py
.
03:16
The @user_passes_test
decorator takes at least one parameter, the test to be passed. This test is either a function or, more commonly, a lambda
.
03:28
If you haven’t seen a lambda
before, then think of it as a miniature, anonymous function. After the lambda
keyword is the named parameter for the lambda
, which in this case is user
. To the right of the colon (:
) is the test.
03:43
This test looks at the HttpRequest.user.is_staff
attribute. If it’s True
, then the test passes. For more information about lambda
functions and how they work, check out the Real Python How to Use Python Lambda Functions course.
04:02
With the new view in place, update your Blog/urls.py
file to register it.
04:16
You now see that visiting /staff_place/
signed in with different accounts gives you different results. Don’t forget that you can always go to /accounts/logout/
to sign out from your current user account.
04:30
As you’ll see onscreen, bob
isn’t staff, so he’s sent back to the login page. sylvia
is a staff member, so she can see the view.
04:40
The superuser is both staff and a superuser and can also see the view. The manage.py createsuperuser
command that you used to create the superuser automatically sets superuser accounts to be staff.
04:56
Under the covers, the @login_required
decorator actually calls the @user_passes_test
decorator and uses the following test. All the @login_required
decorator is doing is checking that the user’s is_authenticated
value is True
, which will be the case for any authenticated account.
05:14
Try experimenting a bit yourself. Add other views, or change the test given to the @user_passes_test
decorator to see how it affects the code.
05:24 Having seen how to restrict views, in the next section you’ll see how to message your users once they are logged in.
Become a Member to join the conversation.
Dmitrii on Sept. 16, 2023
Hi Darren!
Thank you for the course!
I have a question. Is there a mixin for class based view with same functionality as @user_passes_test?
Thank you.
Dmitrii.