abrookins/quest

Example app for the book The Temple of Django Database Performance, 2nd Edition

django
lms

Quest

Example Django project for The Temple of Django Database Performance by Andrew Brookins.

This tree is the code/ submodule of the book repo, on branch temple-book. Listings in the book include:: files from here.

Versions

The runnable app targets Python 3.12 and Django 4.2. That is the last LTS whose ORM APIs still match the book (select_related, prefetch_related, iterator, JSONField, GIN indexes, concurrent index operations) without rewriting the listings.

Django 3.0 (the original pin) does not install on Apple Silicon and does not run against Postgres 15+.

Setup (Docker)

Docker is the default. Postgres, Redis, and Django run as Compose services. This is also the path later updates will use when the profiling chapter grows a local Grafana and OpenTelemetry stack.

From this directory:

make build
make dev          # http://127.0.0.1:8000/
make test
make superuser

If port 8000 is already taken:

QUEST_WEB_PORT=8001 make dev

Postgres is published on host port 15432 (psql -h 127.0.0.1 -p 15432 -U quest). Redis stays on the Compose network so it does not collide with a host redis-server.

make logs         # follow Django
make down         # stop the stack
make generate-events NUM=500000 USER_ID=1

Frontend asset watch is opt-in: docker compose --profile frontend up.

Without Docker

Postgres 16 and Redis on the host, plus a Python 3.12 venv. On macOS:

brew install postgresql@16 redis
brew services start postgresql@16
brew services start redis

If brew services does not listen:

pg_ctl -D /opt/homebrew/var/postgresql@16 start
redis-server --daemonize yes

Then:

make local-setup    # .venv, role/database `quest` / password `test`, migrate
make local-test
make local-run      # http://127.0.0.1:8000/  (PORT=8001 if needed)
make local-superuser

The N+1 demo

GET /analytics is intentionally N+1 (Event.objects.all(), template walks event.user.profile.account). GET /analytics_select_related is the book's fix. Do not add select_related to all_events or the chapter demo disappears.

Weather annotation

process_events writes hourly cloud cover from Open-Meteo. No API key.

generate_events does not add coordinates (a 500k run plus weather would blow the free 10,000 calls/day cap). For a small weather demo, with the Compose stack up:

docker compose exec web python manage.py generate_events --num 5 --user-id 1 --with-location
docker compose exec web python manage.py process_events

Generating data for performance problems

make generate-events NUM=500000 USER_ID=1

USER_ID is a Django user id (your superuser is usually 1). The web container must already be running (make dev).

Copyright

This example code is copyright 2020–2026 Andrew Brookins.

Stars
37
100.00% more than last month
Forks
6
Open Issues
18