Django
Django is a "batteries-included" web framework for Python. Out of the box it ships an ORM, database migrations, an authentication system, an auto-generated admin interface, form handling, and protection against common attacks — the pieces most web apps need but that microframeworks leave to you.
That completeness is Django's pitch: for database-backed applications (SaaS products, marketplaces, content platforms), a small team can ship production features fast because the framework has already made the boring decisions. Instagram, Pinterest, and countless startups have scaled on it.
TL;DR
- Django follows MTV (Model–Template–View): models define data, views handle requests, templates render HTML. For APIs, serializers replace templates.
- The ORM turns Python classes into database tables and querysets into SQL — you rarely write raw SQL.
- Migrations are generated from model changes (
makemigrations) and applied withmigrate. - The admin site gives you a production-ready CRUD interface for your models in a few lines.
- Build REST APIs with Django REST Framework (DRF) — serializers, viewsets, and routers.
- Security defaults are strong: CSRF protection, SQL-injection-safe queries, and XSS-escaping templates are on by default.
Quick Example
A working model, view, and URL — the core Django loop:
Core Concepts
Projects and Apps
A Django project is the whole site (settings, root URLs); an app is a self-contained feature module (models + views + templates). Projects contain many apps, and well-built apps are reusable across projects.
The ORM
Models are Python classes; the ORM generates and runs the SQL:
Querysets don't hit the database until iterated — you can build them up conditionally without cost.
Views and URLs
Views take a request and return a response. Function-based views are explicit; class-based views (and DRF viewsets) remove CRUD boilerplate:
URLs map paths to views with typed converters:
The Admin
Register a model and Django generates a full CRUD backend with auth, search, and filters:
For internal tools and content management this replaces weeks of custom UI work.
Migrations
Django diffs your models against migration history and writes the schema changes for you:
Migrations are Python files committed to version control — the same principles as any database migration workflow: never edit an applied migration, and keep them reversible.
REST APIs with Django REST Framework
DRF is the de facto standard for JSON APIs on Django. Serializers validate and shape data; viewsets plus routers generate the endpoints:
This yields GET/POST /articles/ and GET/PUT/PATCH/DELETE /articles/{id}/ with pagination, auth, permissions, and a browsable API UI.
Best Practices
Kill N+1 Queries
The most common Django performance bug: looping over a queryset and touching a relation per row.
Use django-debug-toolbar in development to see the query count per page.
Use a Custom User Model From Day One
Swapping the user model after the first migration is painful. Even if you add nothing yet:
Split Settings by Environment
Keep secrets out of code and vary config with environment variables:
See Secrets Management for how to store the values.
Deploy Behind a Real Server
runserver is development-only. In production run Gunicorn (WSGI) or Uvicorn (ASGI, for async) behind Nginx, and serve static files with WhiteNoise or a CDN:
Django vs Alternatives
Django's ORM, admin, and auth are the differentiators — if you need all three, little else matches its velocity. If you're only exposing a JSON API and want async performance, FastAPI is the leaner choice.
Common Mistakes
Logic in Views That Belongs in Models or Services
Fat views become untestable. Keep views thin — validate input, call a model method or service function, return a response.
Ignoring select_related Until Production Falls Over
N+1 queries are invisible at 10 rows in development and catastrophic at 10,000 rows in production. Profile query counts early (see Query Optimization).
Running With DEBUG = True in Production
Debug mode leaks settings, environment details, and full tracebacks to anyone who triggers an error. It also disables ALLOWED_HOSTS checks. Always DEBUG = False outside development.
Editing Applied Migrations
Once a migration has run anywhere shared, editing it desynchronizes databases. Add a new migration instead.
FAQ
Is Django good for APIs, or only server-rendered sites?
Both. Django REST Framework makes Django one of the most productive API stacks available, and Django Ninja offers a FastAPI-style typed alternative. Server-rendered templates and JSON APIs coexist fine in one project.
Does Django support async?
Yes — Django supports ASGI, async views, and async ORM queries. Coverage has grown steadily, but the ecosystem (and most middleware) is still predominantly sync; if your workload is truly async-first, FastAPI may fit better.
Is Django too slow for scale?
Framework overhead is rarely the bottleneck — the database is. Instagram served hundreds of millions of users on Django. Standard scaling tools apply: caching, query optimization, read replicas, and horizontal app servers.
What database should I use with Django?
PostgreSQL is the community default and gets the most feature support (e.g. JSONField indexing, full-text search). SQLite is fine for development and small deployments.
Django or Flask for a new project?
If the project is database-backed with users, auth, and an admin need — Django. If it's a small service, a webhook handler, or you want to choose each component yourself — Flask or FastAPI.
Related Topics
- Python — The language underneath
- FastAPI — Async-first Python API framework
- REST API Design — Resource and endpoint design
- Database Migrations — Schema-change workflows
- PostgreSQL — Django's preferred database
- Authentication — Sessions, tokens, and user management
- Query Optimization — Fixing slow ORM queries