Django Cookbook
“How would you do X?” — practical, production-ready recipes with the approach, full code, pitfalls and variations.
Django
- Add a required column without downtimeAdding a NOT NULL column (or renaming one) locks the table or breaks the running version during deploys.
- Add full-text search with PostgreSQLSearching with icontains is slow and returns poorly ranked results.
- Add health checks and structured loggingLoad balancers can't tell if the app is ready, and logs are unstructured text that's hard to search.
- Avoid N+1 queries with select_related and prefetch_relatedA list page runs one query per row because templates or serializers follow relationships.
- Cache expensive queries and invalidate on changeA dashboard query takes seconds, but caching it shows stale data after edits.
- Call external APIs concurrently in async viewsA view calls three slow services one after another, so the response takes the sum of their times.
- Configure settings from environment variablesKeep secrets and per-environment values out of settings.py and fail fast when something required is missing.
- Enforce rules with database constraintsValidation in forms and serializers isn't enough: scripts, imports and race conditions still create bad data.
- Harden security settings, including a Content Security PolicyThe app passes development checks but ships without HTTPS enforcement, secure cookies or a CSP.
- Import and update many rows efficientlySaving thousands of rows one by one takes minutes and floods the database with queries.
- Paginate and filter large API listsOffset pagination gets slow and inconsistent on large, frequently changing tables.
- Rate limit API endpoints in DRFLogin and expensive endpoints get hammered by scripts.
- Restrict API objects to their owners in DRFUsers can read or change other users' records by guessing IDs.
- Run background work with Django's tasks frameworkSending emails or generating reports inside requests makes them slow and fragile.
- Start a project with a custom user modelUse email as the login field and keep room to add profile fields later without a painful migration.
- Test views and APIs with pytest-djangoTests are slow, depend on each other, and don't catch query regressions.
- Update stock safely with transactions, F() and select_for_updateTwo customers buy the last item at the same time and both orders succeed.
- Validate uploads and store them in object storageUsers upload files that are too large, the wrong type, or end up on the web server's disk.
- Write an idempotent management commandOperational scripts (cleanups, backfills) are run ad hoc from shells and behave differently each time.
- Write a reversible data migrationA new column needs values computed from existing data, deployed safely with the schema change.