← Back to Django Course | Chapter 9: Class-Based Views | Lesson 3 of 10

ListView Basics

ListView is Django's way of automatically making a page that shows every item from a database table, like a shelf that lists every book in a library.

A Minimal ListView

Setting model on a ListView subclass is enough for Django to query every row of that model and pass it to the template as a list, with zero manual queryset code.

Example: A Minimal ListView

BookListView automatically runs Book.objects.all() and renders it as the "books" context variable.

markup
from django.views.generic import ListView
from .models import Book


class BookListView(ListView):
    model = Book
    template_name = 'books/book_list.html'
    context_object_name = 'books'
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Rendering the List in a Template

The template receives the queryset under the name given by context_object_name (or object_list by default) and can loop over it with the standard {% for %} template tag.

Example: Rendering the List in a Template

The {% for %} tag iterates the books queryset passed in by BookListView, with {% empty %} handling the zero-results case.

markup
{% for book in books %}
  <p>{{ book.title }}</p>
{% empty %}
  <p>No books yet.</p>
{% endfor %}
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Customizing the Queryset

Overriding get_queryset() lets you filter, order, or limit which objects ListView shows, instead of always showing every row via the model attribute alone.

Note: Always return a queryset (not a list) from get_queryset() so pagination and further chaining still work.

Example: Customizing the Queryset

get_queryset() overrides the default Book.objects.all() with a filtered, ordered queryset.

markup
from django.views.generic import ListView
from .models import Book


class PublishedBookListView(ListView):
    model = Book

    def get_queryset(self):
        return Book.objects.filter(is_published=True).order_by('title')
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}
Common Mistakes
  1. Forgetting that ListView's default context variable name is object_list (or "<model_name>_list"), then referencing the wrong name in the template.
  2. Not setting template_name and being surprised by Django's auto-generated default template path convention.
  3. Trying to filter the queryset by editing model = Model instead of overriding get_queryset().
Chapter Summary
  • ListView displays a list of objects from a model or queryset without writing a manual view function.
  • The context variable defaults to object_list, but context_object_name can rename it.
  • Override get_queryset() to filter, order, or otherwise customize which objects appear.
  • ListView automatically looks for a template named <app>/<model>_list.html unless template_name is set.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.