Menu
CoddyTech

The Authors Page

Part of the Models and the Admin section of Coddy's Django journey. Lesson 22 of 23.

Your bookshelf has a page per book but none for authors. This project builds one from what you know: a view that queries the database, a URL, a template that follows relations, and a QuerySet that does not run a query per row.

Each author is listed with their books: a loop over the authors, and inside it a loop over each author's books. Without help the inner loop runs one query per author. select_related() cannot help, because from an author to their books is a reverse relation. Its partner, prefetch_related(), fetches the related rows of every object in the list with one more query. Book.objects.prefetch_related("loans") fetches every book's loans in one extra query. It takes the related name.

The task says what the page must do; the code is yours.

challenge icon

Challenge

Medium

Build an Authors page.

  1. In books/views.py, write author_list: render books/author_list.html with every author, using prefetch_related().
  2. In books/urls.py, add authors/ named authors.
  3. In author_list.html, give each author a <section class="author">: the name in an <h2>, one <li> per book linking its title to its page.
  4. In books/base.html, link Authors in the <header>.

Click Authors: Herbert lists Children of Dune and Dune.

Try it yourself

from django.shortcuts import get_object_or_404, render

from .models import Book


def home(request):
    books = Book.objects.select_related("author")
    return render(request, "books/home.html", {"books": books})


def book_detail(request, pk):
    book = get_object_or_404(Book, pk=pk)
    return render(request, "books/book_detail.html", {"book": book})


def search(request):
    q = request.GET.get("q", "")
    books = Book.objects.filter(title__icontains=q).select_related("author")
    return render(request, "books/search.html", {"q": q, "books": books})

All lessons in Models and the Admin

Practice on your own: Django playground