Authentication

You've been using Django's built-in authentication system since lesson 6, every time you logged into the admin site. django.contrib.auth gives you user accounts, password hashing, login/logout views, and a way to check who's signed in — all ready to use in your own pages, too.

Logging in

Django provides a ready-made login view — you only need to supply the template:

Python mysite/urls.py
from django.contrib.auth import views as auth_views

urlpatterns = [
    # ... your other patterns
    path('login/', auth_views.LoginView.as_view(), name='login'),
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]
HTML registration/login.html
<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Log in</button>
</form>

LoginView handles checking the username and password against the database, hashing comparisons included, and starting the session — none of that logic is something you write by hand.

Checking who's logged in

Every request has a request.user attribute — either the logged-in User, or an AnonymousUser if nobody's signed in:

Python blog/views.py
def dashboard(request):
    if request.user.is_authenticated:
        message = f"Welcome back, {request.user.username}!"
    else:
        message = "Please log in."
    return render(request, 'dashboard.html', {'message': message})

request.user.is_authenticated is the standard check — it works safely for both real users and AnonymousUser, unlike checking request.user is not None, which would always be true either way.

Restricting a whole view

For a view that should only be reachable while logged in, the @login_required decorator is simpler than checking is_authenticated yourself:

Python blog/views.py
from django.contrib.auth.decorators import login_required

@login_required
def dashboard(request):
    return render(request, 'dashboard.html', {'user': request.user})
Visiting /dashboard/ while logged out
Redirects to /accounts/login/?next=/dashboard/

An anonymous visitor hitting a @login_required view is redirected straight to the login page, with the original URL preserved in ?next= — so after logging in, Django sends them right back to the page they were trying to reach.

Note: Django hashes passwords automatically (PBKDF2 by default) — you never store or compare plaintext passwords yourself, and you never should, in Django or any other framework. Trying to "simplify" this by writing your own password comparison is a common and serious security mistake; let django.contrib.auth handle it.
Course complete: that covers the Django course from top to bottom — starting a project and app, routing URLs to views, rendering HTML with templates and template inheritance, defining models and turning them into real database tables with migrations, the free admin dashboard, forms with built-in validation and CSRF protection, querying data through the ORM's .filter()/.get()/.exclude(), serving static files and user uploads, and finally login/logout and restricting views to signed-in users. From here, the natural next steps are Django REST Framework for building an API, and deploying a real project behind a proper web server instead of the development one used throughout this course.