Django
Handbook
A practical guide covering everything from your first project to building production-ready REST APIs with Django REST Framework — written for beginners and intermediate developers.
Introduction
Django is a high-level Python web framework built on the principle of "batteries included" — it ships with an ORM, admin panel, authentication system, form library, and more, so you can build production-ready apps without assembling a pile of third-party packages.
Django uses Model-Template-View (MTV). Models define data, Templates define presentation, and Views contain business logic — similar to MVC.
ORM, admin panel, auth, sessions, caching, CSRF protection, migrations — all built in and configured to work together safely by default.
Don't Repeat Yourself. Django's ORM, class-based views, and template inheritance all encourage defining things once and reusing everywhere.
Request / Response Cycle
Installation
pip freeze > requirements.txt.Project Structure
INSTALLED_APPS in settings.py.Settings
Models & ORM
A Model is a Python class that maps to a database table. Django's ORM (Object-Relational Mapper) lets you query and manipulate the database entirely in Python — no raw SQL needed for most tasks.
Common Field Types
| Field | Purpose | Key Options |
|---|---|---|
| CharField | Short text with a max length | max_length (required) |
| TextField | Long text, no length limit | — |
| IntegerField / BigIntegerField | Whole numbers | validators |
| FloatField / DecimalField | Decimal numbers | max_digits, decimal_places |
| BooleanField | True/False | default |
| DateField / DateTimeField | Dates and datetimes | auto_now, auto_now_add |
| SlugField | URL-friendly identifiers | unique |
| ImageField / FileField | File uploads | upload_to |
| ForeignKey | Many-to-one relationship | on_delete, related_name |
| ManyToManyField | Many-to-many relationship | through, blank |
| OneToOneField | One-to-one relationship | on_delete, related_name |
| JSONField | JSON data (PostgreSQL native) | default, encoder |
ORM Queries
Migrations
makemigrations after editing models.py, and commit migration files to version control.Views
Function-Based Views (FBV)
Class-Based Views (CBV)
- Simple one-off logic that doesn't fit a generic pattern
- Beginners — easier to read and debug
- Views with complex custom logic or multiple HTTP methods
- CRUD operations — ListView, DetailView, CreateView, etc.
- Shared behaviour via Mixins across multiple views
- When DRY matters most (authentication, permissions)
URLs & Routing
Path Converters
| Converter | Matches | Example |
|---|---|---|
<str:name> | Any non-empty string (default) | /about/ |
<int:pk> | Positive integer | /posts/42/ |
<slug:slug> | ASCII letters, numbers, hyphens, underscores | /posts/hello-world/ |
<uuid:id> | UUID string | /items/550e8400-…/ |
<path:file> | Any string including slashes | /files/img/bg.png |
Templates
Common Template Filters
| Filter | Example | Result |
|---|---|---|
truncatewords:N | {{ text|truncatewords:20 }} | First 20 words + … |
date:"FORMAT" | {{ dt|date:"Y-m-d" }} | 2024-06-15 |
linebreaks | {{ text|linebreaks }} | Newlines → <p>/<br> |
safe | {{ html|safe }} | Render raw HTML (careful!) |
default:"val" | {{ name|default:"Anonymous" }} | Fallback if empty |
length | {{ list|length }} | Count of items |
lower / upper | {{ title|upper }} | Case conversion |
urlencode | {{ query|urlencode }} | URL-encode the string |
Forms
Admin Panel
Auth & Permissions
Middleware
Middleware is a layer that wraps every request/response. Django's built-in middleware handles sessions, authentication, CSRF, and security headers. You can write custom middleware for cross-cutting concerns like logging, rate limiting, or adding custom headers.
Signals
Caching
Static & Media Files
CSS, JavaScript, images bundled with your app. Collected with collectstatic for production. Referenced with {% static 'path' %} in templates.
User-uploaded content (avatars, attachments). Stored in MEDIA_ROOT, served from MEDIA_URL. Use a CDN or object storage (S3) in production.
DRF Introduction
Django REST Framework (DRF) is the standard way to build REST APIs in Django. It adds serializers (like forms for JSON), API views, viewsets, routers, authentication, and permissions on top of Django's solid foundation.
Convert complex types (model instances, querysets) to Python dicts that can be rendered to JSON — and validate incoming JSON back into model instances.
Combine related views (list, detail, create, update, delete) into a single class. Routers auto-generate URLs following REST conventions.
REST API Request Cycle
Serializers
API Views
ViewSets & Routers
API Auth & Permissions
JWT Authentication (recommended for SPAs / mobile)
Custom Permission Classes
Filtering & Pagination
Custom Pagination
Testing APIs
ORM Cheat Sheet
| Lookup / Method | SQL equivalent / Description |
|---|---|
| filter(field=val) | WHERE field = val |
| filter(field__gt=val) | WHERE field > val (also: lt, gte, lte) |
| filter(field__in=[a,b]) | WHERE field IN (a, b) |
| filter(field__isnull=True) | WHERE field IS NULL |
| filter(field__contains='x') | WHERE field LIKE '%x%' (icontains: case-insensitive) |
| filter(field__startswith='x') | WHERE field LIKE 'x%' |
| filter(field__range=(a, b)) | WHERE field BETWEEN a AND b |
| filter(fk__field=val) | JOIN and filter on related model field |
| exclude(field=val) | WHERE NOT field = val |
| order_by('-created_at') | ORDER BY created_at DESC |
| values('field1', 'field2') | SELECT specific columns — returns dicts |
| values_list('field', flat=True) | Returns flat list of values |
| distinct() | SELECT DISTINCT |
| count() | SELECT COUNT(*) |
| exists() | Fast boolean check — uses LIMIT 1 |
| first() / last() | First/last item of QuerySet |
| get_or_create(field=val) | SELECT, INSERT if missing — returns (obj, created) |
| update_or_create(...) | SELECT, UPDATE or INSERT |
| bulk_create([obj1, obj2]) | INSERT multiple rows in one query |
| select_related('fk') | JOIN — avoid N+1 for FK/OneToOne |
| prefetch_related('m2m') | Extra query — avoid N+1 for M2M/reverse FK |
| only('f1','f2') / defer('f3') | Load subset of columns |
| annotate(n=Count('related')) | Add computed column per row |
| aggregate(total=Sum('amount')) | Compute across all rows — returns dict |
Management Commands
| Command | Description |
|---|---|
| runserver [port] | Development server (default port 8000) |
| startproject name . | Create a new Django project |
| startapp name | Create a new Django app |
| makemigrations [app] | Generate migration files from model changes |
| migrate [app] [name] | Apply / roll back migrations |
| showmigrations | List all migrations and their applied status |
| sqlmigrate app 0001 | Print the SQL a migration would run |
| createsuperuser | Create an admin user interactively |
| shell | Interactive Python shell with Django loaded |
| shell_plus | Enhanced shell (django-extensions) — auto-imports all models |
| dbshell | Opens the database CLI (psql, sqlite3, etc.) |
| collectstatic | Gather static files into STATIC_ROOT for deployment |
| test [app.tests] | Run the test suite |
| check --deploy | Security and configuration audit for production |
| dumpdata app.Model | Serialize data to JSON fixture |
| loaddata fixture.json | Load fixture data into the database |
| flush | Delete all data in the database (keep tables) |
Deployment Checklist
- Set
DEBUG = Falsein production - Use a long random
SECRET_KEYfrom env - Set
ALLOWED_HOSTSto your domain - Enable
SECURE_SSL_REDIRECT = True - Set
CSRF_COOKIE_SECURE = True - Set
SESSION_COOKIE_SECURE = True
- Switch to PostgreSQL — not SQLite
- Use connection pooling (PgBouncer)
- Store media on S3/GCS, not the server
- Run
collectstaticin CI/CD - Use WhiteNoise for static files behind gunicorn
- Use gunicorn (sync) or uvicorn (async)
- Enable caching (Redis) for expensive views
- Use
select_related/prefetch_related - Add database indexes on filtered fields
- Use
django-silkor toolbar to profile queries
- Use environment variables for all secrets
- Set up structured logging (JSON to stdout)
- Configure error tracking (Sentry)
- Run migrations in CI before deploy
- Set up health check endpoint