Unit 1: Introduction to Django
I. Orientation: The Framework and Its Governing Ideas
Django is a high-level, open-source web framework written in Python, created in 2003 at the Lawrence Journal-World newspaper in Lawrence, Kansas by Adrian Holovaty and Simon Willison, and released publicly under the BSD licence in July 2005. It is named after the guitarist Django Reinhardt and is maintained by the Django Software Foundation (founded 2008). Because it grew inside a newsroom, its design assumes rapid, deadline-driven development of database-backed, content-heavy sites — the slogan is "The web framework for perfectionists with deadlines."
Defining properties that the rest of the unit depends on:
- Batteries-included: ORM, template engine, form handling, authentication, session management, an automatic admin site and a development server all ship in the box — no assembling of separate libraries.
- MVT architecture: Django's variant of MVC — Model (data layer,
models.py), View (business logic,views.py), Template (presentation,.htmlfiles). The "controller" role is played by the framework itself via URL dispatching (urls.py). - DRY (Don't Repeat Yourself): a fact lives in one place — e.g. a model field defined once generates the database column, the form widget and the admin control.
- Loose coupling / pluggability: the unit of reuse is the app, a self-contained Python package that can be dropped into any project by listing it in
INSTALLED_APPS. - Explicit configuration: unlike convention-driven frameworks, Django requires settings to be declared in
settings.py(DEBUG,DATABASES,ALLOWED_HOSTS). - Convention of the request cycle:
URL → urls.py resolver → view function → model/template → HttpResponse.
II. Introduction to Django
Positioning the framework among Python web tools
A. What Django Is and Why It Exists
- Definition: a server-side (back-end) framework that maps HTTP requests to Python callables and returns HTTP responses, with an ORM abstracting SQL.
- Full-stack vs micro-framework: Flask supplies routing and templating only; Django supplies ORM, migrations, admin and auth as well. Choose Flask for a 100-line API, Django for a site with users, permissions and a schema.
- Security defaults: CSRF tokens required on POST forms, SQL injection prevented by parameterised ORM queries, XSS prevented by auto-escaping in templates, passwords stored with PBKDF2 by default.
- Scale evidence: Instagram, Pinterest, Mozilla and Disqus are built on Django, demonstrating it is not limited to small sites.
- Versioning: feature releases roughly every 8 months; LTS releases (e.g. 3.2, 4.2) receive ~3 years of security support — production projects normally pin to an LTS.
III. Installing Python and Django
Environment setup and dependency isolation
A. Installing Python
- Version requirement: Django 4.2 requires Python 3.8+; always verify with
python --version(Windows) orpython3 --version(macOS/Linux). - Windows installer caveat: tick "Add Python to PATH" during installation, otherwise
pythonandpipare unresolved in the terminal. - pip: the package installer, bundled since Python 3.4; check with
pip --version.
B. Installing Django
Django is never installed globally for real work — it is installed inside a virtual environment, an isolated directory holding its own site-packages, so Project A can use Django 3.2 while Project B uses 4.2.
python -m venv myenv # create the environment
myenv\Scripts\activate # activate (Windows)
source myenv/bin/activate # activate (macOS / Linux)
pip install django # latest version
pip install django==4.2.11 # a pinned version
python -m django --version # verify
pip freeze > requirements.txt # record dependenciesdeactivate: returns to the system interpreter; the shell prompt prefix(myenv)indicates the environment is active.requirements.txt: reinstalled elsewhere withpip install -r requirements.txt, guaranteeing reproducible builds.
IV. Setting up Project in Editor
Making the IDE aware of the interpreter
A. Editor Configuration
- VS Code: open the project folder, then Ctrl+Shift+P → "Python: Select Interpreter" and choose
./myenv/Scripts/python.exe; without this, imports such asfrom django.db import modelsare flagged as unresolved. - Useful extensions: Python (Microsoft), Pylance for IntelliSense, and a Django template extension so
{% %}and{{ }}tags are highlighted in.htmlfiles. - PyCharm Professional: offers a Django project type that sets
DJANGO_SETTINGS_MODULEand runsmanage.pytasks from a dedicated console. - Integrated terminal: run all
manage.pycommands from the directory containingmanage.py, with the venv active. .gitignoreessentials: excludemyenv/,__pycache__/,*.pyc,db.sqlite3and any.envfile holdingSECRET_KEY.
V. Projects and Apps Overview
The two-level unit of organisation
A. The Distinction
- Project: the whole website — a container holding configuration (settings, root URLconf, WSGI/ASGI entry point). One project per site.
- App: a component doing one job — a blog, a poll, an authentication module. A project contains many apps; one app may be reused in many projects.
- Django's own analogy: an app is a "web application that does something"; the project is "a collection of configuration and apps for a particular website."
- Registration: an app is inert until its name is added to
INSTALLED_APPSinsettings.py; only then are its models discovered by migrations and its templates found by the loader. - Built-in apps already listed:
django.contrib.admin,.auth,.contenttypes,.sessions,.messages,.staticfiles. - Design rule of thumb: if a feature could be published to PyPI independently (e.g. a comments system), it deserves its own app.
VI. Creating Your First Project
Command, output and first run
A. The startproject Command
django-admin startproject mysite # creates outer mysite/ + inner mysite/
cd mysite
python manage.py runserver # http://127.0.0.1:8000/- The trailing dot:
django-admin startproject mysite .creates the config package in the current directory, avoiding the duplicatedmysite/mysite/nesting. - First run output: the "rocket ship" success page appears only while
DEBUG = True. - Unapplied-migrations warning:
runserverwarns of 18 unapplied migrations from the built-in apps;python manage.py migratecreatesdb.sqlite3with tables such asauth_useranddjango_session. - Custom port/host:
python manage.py runserver 8080orrunserver 0.0.0.0:8000to expose on a LAN. The development server auto-reloads on file save and must never be used in production.
VII. Project Structure
What each generated file does
A. File-by-File Anatomy
mysite/ # outer container (name is arbitrary)
├── manage.py # command-line utility
└── mysite/ # configuration package
├── __init__.py # marks the directory as a Python package
├── settings.py # all configuration
├── urls.py # root URLconf ("table of contents")
├── asgi.py # ASGI entry point (async servers)
└── wsgi.py # WSGI entry point (Gunicorn, mod_wsgi)settings.pykey variables:BASE_DIR:Path(__file__).resolve().parent.parent— the project root, used to build paths.SECRET_KEY: cryptographic signing of sessions and CSRF tokens; must be kept out of version control.DEBUG:Truegives full tracebacks; must beFalsein production, which then requiresALLOWED_HOSTSto list valid domains.INSTALLED_APPS,MIDDLEWARE(ordered request/response hooks),TEMPLATES,DATABASES(SQLite by default),STATIC_URL = 'static/'.
urls.py: containsurlpatterns = [path('admin/', admin.site.urls)]; app URLs are attached withinclude().db.sqlite3: appears only after the firstmigrate.
VIII. django-admin & manage.py Commands
The two command-line entry points
A. The Two Utilities Contrasted
django-admin: installed on PATH by pip, project-independent; used before a project exists — chieflystartproject. It has no knowledge ofDJANGO_SETTINGS_MODULEunless it is set manually.manage.py: auto-generated per project; a thin wrapper that setsos.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')and then callsexecute_from_command_line. Use it for everything after the project is created, because it knows the project's settings and database.
B. Command Reference
| Command | Effect |
|---|---|
startproject <name> |
Scaffold a new project |
startapp <name> |
Scaffold a new app |
runserver [port] |
Start the auto-reloading dev server |
makemigrations |
Turn model changes into migration files |
migrate |
Apply migrations to the database |
createsuperuser |
Create an admin account |
shell |
Python REPL with Django loaded |
dbshell |
Open the database's own client |
test |
Run the test suite |
collectstatic |
Gather static files for deployment |
showmigrations |
List migrations and their applied state |
- Discovery:
python manage.py helplists all commands grouped by the app supplying them; apps can add their own via amanagement/commands/directory.
IX. App Structures
Files generated inside an app
A. Anatomy of an App Package
blog/
├── __init__.py
├── admin.py # register models with the admin site
├── apps.py # BlogConfig class; app metadata
├── migrations/ # schema history, starts with __init__.py only
│ └── __init__.py
├── models.py # database tables as Python classes
├── tests.py # test cases
└── views.py # request-handling functions/classesmodels.py: each class subclassesdjango.db.models.Model; each attribute (CharField,IntegerField) becomes a column.views.py: a view receives anHttpRequestand returns anHttpResponse—def index(request): return HttpResponse("Hello").apps.py: holdsclass BlogConfig(AppConfig)withdefault_auto_fieldandname = 'blog'; referenced byINSTALLED_APPS.- Files not generated but conventionally added:
urls.py(app-level URLconf),forms.py,templates/blog/,static/blog/— the app-name subdirectory prevents template name collisions between apps.
X. Creating an App
From scaffold to first response
A. The Full Sequence
python manage.py startapp blog- Register it in
settings.py:
PYTHONINSTALLED_APPS = [ ..., 'blog', ] # or 'blog.apps.BlogConfig' - Write a view in
blog/views.py:
PYTHONfrom django.http import HttpResponse def index(request): return HttpResponse("Welcome to the blog.") - Create
blog/urls.py:
PYTHONfrom django.urls import path from . import views app_name = 'blog' urlpatterns = [path('', views.index, name='index')] - Include it in
mysite/urls.py:
PYTHONfrom django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('blog/', include('blog.urls')), ] - Run
python manage.py runserverand visithttp://127.0.0.1:8000/blog/.
B. Applications and Limitations
- Application: the same app, unmodified, can be pip-packaged and reused across projects — the practical payoff of loose coupling.
- Naming constraints: an app name must be a valid Python identifier and must not clash with an installed module (
test,django,json). - Limitation:
startappdoes not createurls.py,forms.pyor template folders — these must be added by hand. - Limitation: adding an app to
INSTALLED_APPSafter writing models still requiresmakemigrations blogfollowed bymigrate; otherwise the tables never exist and queries raiseOperationalError: no such table.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →