CodeOath
← All posts
Python65 min total · 18 parts

Django Fundamentals: The ORM, Migrations, and Shipping a Real App

Part 14 of 18 · ~1 min

Authentication: Knowing Who's Asking

from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin

@login_required
def request_loan(request, pk):
    ...

class MyActiveLoansView(LoginRequiredMixin, ListView):
    model = Loan
    login_url = "/accounts/login/"
# inside any view, once AuthenticationMiddleware has run:
request.user                       # a real User, or an AnonymousUser instance — never None
request.user.is_authenticated      # True/False — safe to check even when nobody's logged in
request.user.has_perm("loans.mark_returned")   # a custom permission, checked here

A visitor who's never logged in still gets a real object sitting behind request.user — an AnonymousUser instance, standing in so the attribute is never simply absent. That's worth knowing specifically because it means request.user is None can never catch a logged-out visitor; it'll always evaluate False, logged in or not, since there's always something there. .is_authenticated is the attribute actually built to answer the question. Four permissions get generated automatically for every model — add_, change_, delete_, and view_, each one prefixed onto the model's name — and has_perm checks a user against those plus anything a model's own Meta.permissions defines on top, like the custom loans.mark_returned that decides who's allowed to close out a loan that isn't theirs. A Group bundles a set of permissions under one name so they can be handed to a whole batch of users in one assignment instead of one at a time.