Challenge 1: Write a Registration View — Possible Solution ==================================================================== # catalog/views.py from django.contrib.auth.models import User from django.contrib.auth import login from django.shortcuts import render, redirect def register(request): if request.method == "POST": username = request.POST.get("username", "") email = request.POST.get("email", "") password = request.POST.get("password", "") if not username or not password: return render(request, "registration/register.html", { "error": "Username and password are required.", }) if User.objects.filter(username=username).exists(): return render(request, "registration/register.html", { "error": "That username is already taken.", }) user = User.objects.create_user( username=username, email=email, password=password, ) login(request, user) return redirect("dashboard") return render(request, "registration/register.html") # catalog/urls.py from django.urls import path from . import views urlpatterns = [ path("register/", views.register, name="register"), ] WHY THIS WORKS -------------- - User.objects.create_user(...) is used instead of User.objects.create() or a raw ModelForm.save() — create_user() specifically hashes the password before storing it; the plain ORM .create() would store whatever string was passed for `password` completely unhashed, a serious vulnerability if this code path were ever accidentally used. - Checking User.objects.filter(username=username).exists() before creating the user prevents a Django-level IntegrityError from an attempted duplicate username, turning it into a friendly error message instead of a 500 error. - login(request, user) immediately after creating the account establishes the session right away — the new user doesn't need to separately submit a login form right after registering, a common real-world UX pattern. - request.POST.get(...) with default empty strings (rather than direct indexing) avoids a KeyError if a field is missing from the submitted form data, matching the defensive pattern used in earlier chapters' form-handling views.