Challenge 1: Convert an FBV to a ListView — Possible Solution
====================================================================
# BEFORE — Course 1's function-based view
def book_list(request):
books = Book.objects.all()
return render(request, "catalog/book_list.html", {"books": books})
# AFTER — catalog/views.py
from django.views.generic import ListView
from .models import Book
class BookListView(ListView):
model = Book
template_name = "catalog/book_list.html"
context_object_name = "books"
paginate_by = 10
# catalog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.BookListView.as_view(), name="book-list"),
]
{% for book in books %}
- {{ book.title }}
{% endfor %}
{% if is_paginated %}
{% endif %}
WHY THIS WORKS
--------------
- model = Book tells ListView what to query (Book.objects.all() by
default, exactly matching the original FBV's query) — context_object_name
= "books" ensures the template variable name stays "books", matching
what the existing template already expects, rather than ListView's
default name of "object_list".
- paginate_by = 10 is the entire pagination implementation — the
original FBV would have needed a Paginator import, manual page-number
handling from request.GET, and slicing the queryset by hand to achieve
the same result; ListView does all of that internally.
- is_paginated, page_obj, and paginator are all automatically added to
the template context by ListView whenever paginate_by is set — no
changes needed in the view itself to make that pagination UI possible,
only in the template that displays it.
- The urls.py entry changed from views.book_list (a plain function) to
views.BookListView.as_view() (per Course 1's Views chapter, this
.as_view() conversion step is required for any class-based view).