How Django works: the framework you already built
You've built nearly every piece of Django by hand across these guides — a WSGI callable, a route table, middleware, an ORM, templates — and watched the CSRF defense defeat a forged form. This overview assembles the map: the startproject skeleton file by file, the full life of a request through the framework, and a side-by-side of your ~150 lines against Django's modules. Two simulators run the pipeline and the correspondence.
mindmap — quick refresh
Prerequisites: this is the capstone — it assembles WSGI, the tiny ORM, HTML forms & CSRF, SSR, packaging, and OOP. Have at least WSGI and the ORM under your belt. Time: ~40 minutes reading, then the official tutorial.
Django is ~350,000 lines of Python, twenty years old (2005, named after guitarist Django Reinhardt), and runs Instagram. It is also — and this is the claim these guides have been quietly proving — a framework you have already built. A WSGI callable, a route table, a middleware onion, a self-describing ORM, template rendering: you wrote each one small — and the sixth piece, the CSRF token, you watched defeat a forged form in the forms guide. What Django adds is not new kinds of machinery; it's the same machinery industrialized, with twenty years of edge cases handled. So this guide is not a tutorial — the official one is excellent — it's the map that stops Django from ever feeling like magic.
Install and read the skeleton
Setup is the packaging workflow, verbatim (Windows: py -m venv .venv, then .venv\Scripts\activate):
python3 -m venv .venv && source .venv/bin/activate
pip install django # 6.1 at the time of writing
django-admin startproject foodsite
cd foodsite && python manage.py startapp orders
That generates a tree, and here's the point of this whole article — annotate it with where you've been:
foodsite/
├── manage.py ← runs commands inside your venv'd project
├── foodsite/ ← the project: plumbing
│ ├── settings.py ← config: MIDDLEWARE list, DATABASES, apps
│ ├── urls.py ← the route table → How WSGI works
│ ├── wsgi.py ← the WSGI callable → How WSGI works
│ └── asgi.py ← its async sibling → (same guide, last section)
└── orders/ ← an app: your actual features
├── models.py ← classes ↔ tables → How ORMs work
├── views.py ← request → response → SSR labs, WSGI
├── admin.py ← free CRUD UI → (new! see below)
├── migrations/ ← schema history → (new! see below)
└── tests.py
Open wsgi.py and enjoy the punchline — after the comments it's two meaningful lines, ending in application = get_wsgi_application(). The entire framework is inside a callable with the exact signature you implemented from scratch. Gunicorn cannot tell your 40-line framework and Django apart, because there is nothing to tell apart.
The life of a request
Everything Django does happens inside one application(environ, start_response) call — so let's trace GET /students/42/ through the whole machine, station by station. You built every station; Django's contribution is the assembly. The seven middleware in a fresh settings.py are your onion written vertically — SecurityMiddleware, SessionMiddleware, CommonMiddleware, CsrfViewMiddleware, AuthenticationMiddleware, MessageMiddleware, XFrameOptionsMiddleware — request descending, response climbing, any layer able to short-circuit (that's CSRF rejection happening before your view ever runs):
Note what the trace makes obvious: a Django "view" is your WSGI view with better luggage — request is environ upgraded to an object (request.GET, request.POST pre-parsed, request.user attached by the auth middleware), and returning an HttpResponse replaces calling start_response by hand.
Yours ↔ Django's, line by line
The correspondence deserves to be exact, not hand-waved. Left column: code you have actually written in these guides. Right: the Django file where the same job lives:
Written out once, view-layer included:
# you wrote (tinyorm + framework.py): # Django (models.py / views.py / urls.py):
class Student(Model): class Student(models.Model):
name: str name = models.CharField(max_length=100)
course: str course = models.CharField(max_length=100)
Student.filter(course="AI") Student.objects.filter(course="AI")
@app.route(r"/students/(?P<sid>\d+)/") path("students/<int:sid>/", views.detail)
def detail(environ, sid): def detail(request, sid):
return "200 OK", f"<h1>…{sid}</h1>" s = Student.objects.get(pk=sid)
return render(request, "detail.html", {"s": s})
Differences worth respecting: Django's fields carry database detail (CharField(max_length=100)) because migrations generate real DDL from them; objects.filter() returns a lazy QuerySet (SQL runs on iteration, not on the call — the big upgrade over our eager tiny ORM); and render() is the SSR template merge with auto-escaping on by default.
The batteries you didn't build
Four additions have no counterpart in your hand-built stack — these are what you're actually adopting Django for:
- The admin. Two lines in
admin.py(admin.site.register(Student)) and Django serves a full create/read/update/delete UI for your models — generated from the same self-description your tiny ORM introspected. This is the killer feature that made Django famous in newsrooms. - Auth, complete. Everything authentication vs authorization described, built for real: sessions, users, groups, password hashing,
@login_required. OurGateKeeperwas just a path-prefix blocker — Django's auth middleware is the same short-circuit pattern grown into genuine session machinery. - Migrations.
makemigrationsdiffs your models against schema history and writes the SQL for you — theCREATE TABLEyou typed by hand in PostgreSQL 101, plus theALTER TABLEfor every schema change after it;migrateapplies them in order, on any machine. - Secure defaults, stacked. Values through SQL placeholders (ORM guide), CSRF tokens checked by middleware (forms guide), template auto-escaping (SSR part 1's warning, made default), clickjacking and HTTPS headers. Django's philosophy: the safe path is the default path.
The component map: go deeper
Why does Django decompose into these particular modules? Because each one owns exactly one job from the request's journey — and every one of those jobs is something you've already done small. So use this table as a directory: whenever a component starts to feel like magic, the linked guide rebuilds it by hand.
| Django component | The job it owns | How it works under the hood |
|---|---|---|
wsgi.py / django.core.handlers | speak the server ↔ framework contract | How WSGI works |
urls.py / django.urls | match the path, pick the view | How WSGI works — routing; the patterns: How regular expressions work |
settings.MIDDLEWARE | wrap every request and response | How WSGI works — the onion |
django.http — HttpRequest, HttpResponse | model the HTTP conversation | How HTTP works |
views.py | turn a request into a response | SSR in pure Python, part 1 and part 2 |
models.py / django.db.models — the ORM | translate objects ↔ rows | How ORMs work |
| the database underneath | store and guard the data | PostgreSQL 101 |
django.template | merge data into HTML, escaping by default | SSR in pure Python, part 1 — the template merge |
django.forms + CsrfViewMiddleware | read user input safely | How HTML forms work |
django.contrib.sessions + django.contrib.auth | who are you, and what may you do? | How auth works |
manage.py runserver — the dev server | the accept → parse → route → respond loop | How HTTP servers work |
your venv + pip install django | get the framework onto your machine | How Python packages work |
django.contrib.staticfiles, gunicorn, the proxy | serve it on the real internet | How deployment works — the one row that points ahead: on the roadmap it's your next guide, not one behind you |
django.contrib.admin | free CRUD UI from model metadata | no guide yet — it's generated from the ORM's self-description (How ORMs work) |
django.db.migrations | write schema history from your models | no guide yet — the DDL it generates is PostgreSQL 101 by machine |
Two rows say "no guide yet" on purpose: the admin and migrations are the genuinely new machinery you adopted Django for, and honest gaps beat pretend coverage. Everything else in the framework, you can now open from the inside.
Your path from here
Do the official Django tutorial next — it will feel like revision, and that's the intended effect. Part 1 (project setup) is the WSGI + packaging guides; part 2 (models, admin) is the ORM guide plus the free UI; part 3 (views, URLconfs) is the framework you wrote; part 4 (forms) is the forms guide with csrf_token finally explained by mechanism, not incantation. And when something breaks, read the error page top-down without fear: every frame in that traceback — middleware, URL resolver, view, ORM — is a layer you have built with your own hands.
Takeaways
- Django is your stack, industrialized — WSGI callable, route table, middleware onion, self-describing ORM, template merge: nothing in the core is a new kind of thing.
- The skeleton is a map, not a mystery —
wsgi.pyis your callable,urls.pyyour route list,models.pyyour tiny ORM,settings.MIDDLEWAREyour onion written vertically. - A request crosses ~7 middleware, one URLconf, one view — and can be short-circuited early (CSRF, auth) exactly like your
GateKeeper; responses climb back out through every layer. requestisenvironwith luggage — pre-parsed GET/POST, an attacheduser;HttpResponsereplaces hand-rolledstart_response.- Adopt Django for the batteries — admin, auth, migrations, lazy QuerySets, and safe-by-default settings are the 350k lines you shouldn't rewrite.
- Debug fearlessly — every layer in a Django traceback is one you've built small; read top-down and name the station.
References
- Django Software Foundation. (n.d.). Django at a glance (Django documentation). Retrieved August 17, 2026, from https://docs.djangoproject.com/en/stable/intro/overview/
- Django Software Foundation. (n.d.). Design philosophies (Django documentation). Retrieved August 17, 2026, from https://docs.djangoproject.com/en/stable/misc/design-philosophies/
- Django Software Foundation. (n.d.). FAQ: General (Django documentation). Retrieved August 17, 2026, from https://docs.djangoproject.com/en/stable/faq/general/
- Django Software Foundation. (n.d.). Writing your first Django app, part 1 (Django documentation). Retrieved August 17, 2026, from https://docs.djangoproject.com/en/stable/intro/tutorial01/
- Holovaty, A., & Kaplan-Moss, J. (2009). The definitive guide to Django: Web development done right (2nd ed.). Apress.