Python Tutorial
Django Introduction
Django is a high-level Python web framework for building secure, database-backed websites quickly. This section walks through a complete members app, one chapter at a time.
What Is Django?
Django follows the MVT pattern: Model, View, Template. You describe data as Python classes, write views that handle requests, and render HTML templates. Django fills in the rest: URL routing, an ORM, an admin site, forms, authentication, and security defaults.
- Model — the database table, defined in Python.
- View — the function (or class) that receives a request and returns a response.
- Template — HTML with tags that insert data from the view.
Why Django?
- Batteries included: admin, auth, sessions, CSRF protection, and migrations ship with the framework.
- The ORM talks to SQLite, PostgreSQL, MySQL, and more without raw SQL for common work.
- Projects scale from a weekend prototype to a production site.
This tutorial uses a project named mysite and an app named members. Follow every chapter in order and you will have a working CRUD site by the end.
What You Will Build
A members directory where you can:
- Create a project and a
membersapp. - Define a
Membermodel and migrate it to SQLite. - Insert, update, and delete rows from the shell and from views.
- List members in templates, handle 404 pages, and serve CSS.
- Add forms and login so only staff can change data.
Chapters in This Section
| Chapter | You will learn |
|---|---|
| Get Started | Prerequisites and how to check Python |
| Virtual Environment | Isolate Django from other Python projects |
| Install Django | Install the framework with pip |
| Create Project | startproject, files, and runserver |
| Create App | startapp and INSTALLED_APPS |
| Views | Return HTML from a view function |
| URLs | Map paths to views with path() and include() |
| Templates | Render HTML files with context |
| Models | Define tables and run migrations |
| Insert Data | Create rows with the ORM |
| Update Data | Change a saved object |
| Delete Data | Remove rows |
| Update Model | Add fields and migrate again |
| Admin | Create a superuser and register models |
| 404 Template | Custom page-not-found responses |
| Template Variables | {{ output tags |
| Template Tags | Logic with {% tags |
| If Tag | Conditions in templates |
| For Tag | Loop over querysets |
| Include Tag | Reusable navbar and footer |
| QuerySet | all(), count(), laziness |
| QuerySet Get | Fetch one object by id |
| QuerySet Filter | Lookups like __contains |
| QuerySet Order By | Sort results |
| Static Files | CSS, images, and collectstatic |
| Forms | ModelForm, CSRF, POST |
| Authentication | Login, logout, and protected views |
Requirements
- Python 3.10 or newer.
- pip and a terminal (PowerShell, bash, or cmd).
- A code editor such as VS Code or Cursor.
The MVT Pattern
Django follows Model-View-Template, its take on MVC:
| Part | Responsibility |
|---|---|
| Model | Data structure & database access (an ORM class) |
| View | Business logic — receives a request, returns a response |
| Template | HTML with placeholders for dynamic data |
| URLs | Map a URL path to a view |
Project Setup at a Glance
pip install django
django-admin startproject mysite
cd mysite
python manage.py startapp members # create an app
python manage.py migrate # set up the database
python manage.py runserver # http://127.0.0.1:8000/A Django project is the whole site; an app is a reusable feature inside it (e.g. a blog, a members list). One project can contain many apps.
Try It Yourself
Exercise 1: Which command creates a new app called blog?
Show solution
python manage.py startapp blogExercise 2: After changing a model, which two commands update the database?
Show solution
python manage.py makemigrations
python manage.py migrateKey Takeaways
- Django is a batteries-included web framework using the MVT pattern.
- A project holds one or more apps.
manage.pyruns the server, migrations, and admin tasks.- The ORM lets you query the database with Python instead of SQL.
📘 Real-World Deep Dive
Django is the "batteries-included" Python web framework: ORM, admin, auth, forms, templates, migrations, and a powerful URL router. Pair the parts and you can ship a CRUD + REST API in a single weekend.
Real-Life Scenario
A small blog: model + admin + view + URL + template, end to end. After this exercise, you will have the full Django mental model in 50 lines of code.
Real-Life Example
# models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
body = models.TextField()
pub = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey("auth.User", on_delete=models.CASCADE)
class Meta:
ordering = ["-pub"]
indexes = [models.Index(fields=["pub"])]
def __str__(self):
return self.title
# views.py
from django.shortcuts import get_object_or_404, render
from .models import Post
def post_list(request):
posts = Post.objects.select_related("author").order_by("-pub")[:50]
return render(request, "blog/list.html", {"posts": posts})
def post_detail(request, slug):
post = get_object_or_404(Post, slug=slug)
return render(request, "blog/detail.html", {"post": post})
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.post_list, name="list"),
path("<slug:slug>/", views.post_detail, name="detail"),
]
# templates/blog/list.html — minimal
# {% for p in posts %}
# <article><h2><a href="{% url 'detail' p.slug %}">{{ p.title }}</a></h2>
# <p>{{ p.pub|date:"Y-m-d" }} — {{ p.body|truncatewords:30 }}</p></article>
# {% endfor %}Expected Output
(runnable via manage.py runserver; the queryset from Post.objects.select_related(...) is rendered by the template)Common mistakes
- Calling
.all()on a 1 M-row table loads every row — use.iterator()for streaming. - N+1:
post.author.nameinside a loop triggers one query per post; switch toselect_related. - Forgetting
on_delete=models.CASCADEsilently breaks deletes once you migrate.
🚀 Performance & Best Practices
- Add DB indexes on columns used in
filter()— they cost nothing to define and pay off. - Set
CONN_MAX_AGEinsettings.pyto keep long-lived DB connections warm. - Cache the rendered list view with
@cache_page(60 * 5)if reads dominate writes.
🧪 Try It Yourself
- Add a
/api/posts/JSON endpoint using DRF. - Add user login + a "create post" form.
- Deploy with gunicorn + nginx and confirm
collectstaticworks.