django β Full-Stack Web Framework#
What it is#
Django is a batteries-included web framework: ORM, migrations, admin panel, authentication, form handling, and template engine all come built-in. It follows the MTV (ModelβTemplateβView) pattern and enforces a project layout that scales from a simple blog to a large multi-app system.
Install#
pip install django
Create a project and app#
django-admin startproject mysite
cd mysite
python manage.py startapp blog
Output:
(no output β creates directory structure)
Generated structure:
mysite/
βββ manage.py
βββ mysite/
β βββ __init__.py
β βββ settings.py
β βββ urls.py
β βββ wsgi.py
βββ blog/
βββ models.py
βββ views.py
βββ admin.py
βββ migrations/
Define a model#
# blog/models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
published = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self) -> str:
return self.title
Run migrations#
# Add 'blog' to INSTALLED_APPS in mysite/settings.py first
python manage.py makemigrations
python manage.py migrate
Output:
Migrations for 'blog':
blog/migrations/0001_initial.py
- Create model Post
Operations to perform:
Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
Applying blog.0001_initial... OK
Register in admin and create superuser#
# blog/admin.py
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ["title", "published", "created_at"]
list_filter = ["published"]
search_fields = ["title", "body"]
python manage.py createsuperuser
python manage.py runserver
Output:
Username: admin
Email address: admin@example.com
Password: β’β’β’β’β’β’β’β’
Superuser created successfully.
Watching for file changes with StatReloader
Django version 5.1.0, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Browse to http://127.0.0.1:8000/admin/ to log in and manage Post records.
When / why to use it#
- Full web applications that need user auth, admin panel, and a built-in ORM.
- Content-heavy sites (CMS, blogs, e-commerce).
- Teams that want strong conventions and a large ecosystem of third-party apps (
django-rest-framework,django-allauth, etc.).
Prefer Flask for small APIs with no admin requirements. Prefer FastAPI for async, high-performance APIs.
Common pitfalls#
[!WARNING] Never run
manage.py runserverin production β it is single-threaded and not hardened. Usegunicorn+ nginx or a managed platform (Railway, Fly.io, Heroku).
[!WARNING]
DEBUG = Truein production β Django shows full tracebacks with local variable values in the browser whenDEBUG=True. SetDEBUG=FalseandALLOWED_HOSTScorrectly in production, and use environment variables for secret settings.
[!WARNING] Migration conflicts in teams β when two developers add different migrations, you get a conflict. Resolve with:
python manage.py makemigrations --merge.
[!TIP] Use
python manage.py shell_plus(fromdjango-extensions) instead ofmanage.py shellβ it auto-imports all models.
Richer example β class-based view with JSON response#
# blog/views.py
from django.http import JsonResponse
from django.views import View
from .models import Post
class PostListView(View):
def get(self, request):
posts = list(
Post.objects.filter(published=True)
.values("id", "title", "created_at")
.order_by("-created_at")[:10]
)
return JsonResponse({"posts": posts})
# mysite/urls.py
from django.urls import path
from blog.views import PostListView
urlpatterns = [
path("api/posts/", PostListView.as_view()),
]
curl -s http://127.0.0.1:8000/api/posts/
Output:
{"posts": [{"id": 1, "title": "Hello Django", "created_at": "2026-04-25T12:00:00Z"}]}
Essential management commands#
| Command | Purpose |
|---|---|
manage.py runserver | Start dev server on 127.0.0.1:8000 |
manage.py makemigrations | Generate migration files from model changes |
manage.py migrate | Apply pending migrations to the database |
manage.py createsuperuser | Create an admin user |
manage.py shell | Interactive Python shell with Django loaded |
manage.py dbshell | SQL shell for the configured database |
manage.py collectstatic | Copy static files to STATIC_ROOT for serving |
manage.py test | Run the test suite |
manage.py check | Validate project configuration |