Challenge 3: Use reverse() Instead of a Hardcoded Path — Possible Solution ==================================================================== # BEFORE — hardcoded path from django.shortcuts import redirect def create_book(request): # ... save the new book ... return redirect("/books/42/") # a brittle, hand-typed string # AFTER — built from the named route from django.shortcuts import redirect from django.urls import reverse def create_book(request): # ... save the new book, get its real id ... new_book_id = 42 return redirect(reverse("book-detail", kwargs={"book_id": new_book_id})) # Django's redirect() shortcut actually accepts a route name directly too, # making reverse() unnecessary in this exact case — but the explicit form # above demonstrates what's happening either way: def create_book_shortcut_version(request): new_book_id = 42 return redirect("book-detail", book_id=new_book_id) WHY THIS MATTERS IF THE /books/ PREFIX EVER CHANGES ------------------------------------------------------ If the project's root urls.py later changes: path("books/", include("catalog.urls")) to something like: path("library/", include("catalog.urls")) every hardcoded string like "/books/42/" scattered across views, tests, and templates silently starts pointing at a URL that no longer exists — and nothing warns you, because a plain string has no connection to the actual URL configuration. reverse("book-detail", ...) (or the {% url %} template tag), by contrast, asks Django's URL resolver to build the path from the CURRENT url patterns every time it's called — so renaming the prefix, or even restructuring which app owns which routes, updates every call site automatically, with zero find-and-replace required. WHY THIS WORKS -------------- - reverse("book-detail", kwargs={"book_id": 42}) looks up the URL pattern registered under the name "book-detail" (from Challenge 1) and substitutes 42 into its converter slot, producing "/books/42/" — but it computes that path fresh from whatever the actual current routing configuration says, rather than assuming it. - This is the exact same principle behind avoiding hardcoded values anywhere else in a codebase (magic strings, repeated literals) — a named, centrally-defined route is a single source of truth that every other part of the app should reference indirectly.