Cheatsheets / Django

Django Cheatsheet

Complete Django reference. Hit Ctrl+P to print.

manage.py Commands

python manage.py runserverStart development server (port 8000)
python manage.py runserver 0.0.0.0:8080Start server on custom host/port
python manage.py startproject mysiteCreate a new Django project
python manage.py startapp blogCreate a new app within the project
python manage.py makemigrationsGenerate migration files from model changes
python manage.py migrateApply pending migrations
python manage.py migrate app 0003Migrate app to specific migration
python manage.py showmigrationsList all migrations and their status
python manage.py createsuperuserCreate admin user interactively
python manage.py shellInteractive Python shell in project context
python manage.py dbshellOpen database CLI
python manage.py testRun test suite
python manage.py test blog.tests.PostTestsRun specific test class
python manage.py collectstaticCollect static files to STATIC_ROOT
python manage.py checkCheck project for common problems
python manage.py flushDelete all data from database
python manage.py loaddata fixtures.jsonLoad data from fixture file
python manage.py dumpdata blog > fixtures.jsonExport app data to fixture

Models

from django.db import modelsImport models module
class Post(models.Model):Define a model
title = models.CharField(max_length=200)String field with max length
body = models.TextField()Unbounded text field
created = models.DateTimeField(auto_now_add=True)Auto-set timestamp on create
updated = models.DateTimeField(auto_now=True)Auto-set timestamp on save
active = models.BooleanField(default=True)Boolean field with default
user = models.ForeignKey(User, on_delete=models.CASCADE)Foreign key with cascade delete
tags = models.ManyToManyField(Tag, blank=True)Many-to-many relationship
profile = models.OneToOneField(User, on_delete=models.CASCADE)One-to-one relationship
class Meta: ordering = ["-created"]Default ordering for queries
def __str__(self): return self.titleString representation
def get_absolute_url(self): return reverse("post-detail", args=[self.pk])Canonical URL for model

ORM Queries

Post.objects.all()Get all records (returns QuerySet)
Post.objects.get(pk=1)Get single record (raises DoesNotExist if not found)
Post.objects.filter(active=True)Filter records
Post.objects.filter(title__icontains="django")Case-insensitive contains lookup
Post.objects.filter(created__year=2024)Date field lookup
Post.objects.exclude(active=False)Exclude matching records
Post.objects.order_by("-created")Order descending by field
Post.objects.values("id", "title")Return dicts instead of model instances
Post.objects.values_list("id", flat=True)Return list of single field values
Post.objects.count()Count matching records
Post.objects.first() / .last()Get first or last record
Post.objects.exists()Check if any matching records exist
Post.objects.select_related("user")JOIN for ForeignKey (avoids N+1)
Post.objects.prefetch_related("tags")Prefetch for ManyToMany (avoids N+1)
Post.objects.create(title="Hello")Create and save new record
Post.objects.get_or_create(slug="hello", defaults={"title": "Hello"})Get or create record
Post.objects.update_or_create(slug="hello", defaults={"title": "Hello"})Update or create record
Post.objects.filter(active=True).update(views=0)Bulk update
Post.objects.filter(active=False).delete()Bulk delete
from django.db.models import Q; Post.objects.filter(Q(title="x") | Q(body="x"))OR query with Q objects

Views

from django.shortcuts import render, get_object_or_404, redirectCommon view imports
def post_list(request): return render(request, "blog/list.html", {"posts": posts})Function-based view
get_object_or_404(Post, pk=pk)Get or raise Http404
return redirect("post-list")Redirect by URL name
return redirect(post.get_absolute_url())Redirect to model URL
from django.views.generic import ListView, DetailView, CreateViewImport class-based views
class PostList(ListView): model = Post; template_name = "blog/list.html"ListView CBV
class PostDetail(DetailView): model = PostDetailView CBV (uses blog/post_detail.html)
class PostCreate(CreateView): model = Post; fields = ["title", "body"]CreateView CBV
from django.contrib.auth.decorators import login_requiredAuth decorator import
@login_requiredRequire authentication for function view
from django.contrib.auth.mixins import LoginRequiredMixinAuth mixin for CBV
from django.http import JsonResponse; return JsonResponse({"ok": True})Return JSON response

URL Configuration

from django.urls import path, includeImport URL utilities
path("posts/", views.post_list, name="post-list")Basic URL pattern
path("posts/<int:pk>/", views.post_detail, name="post-detail")URL with integer converter
path("posts/<slug:slug>/", views.post_detail, name="post-detail")URL with slug converter
path("blog/", include("blog.urls"))Include app-level URL conf
path("blog/", include("blog.urls", namespace="blog"))Include with namespace
from django.urls import reverse; reverse("post-detail", args=[pk])Reverse URL by name
{% url "post-detail" post.pk %}Reverse URL in template
re_path(r"^legacy/(?P<id>\d+)/$", view)Regex URL pattern

Templates

{{ variable }}Output variable (auto-escaped)
{{ variable|default:"fallback" }}Output with default filter
{{ variable|date:"Y-m-d" }}Format a date
{{ variable|truncatewords:20 }}Truncate to N words
{% if condition %} ... {% elif ... %} ... {% else %} ... {% endif %}Conditional block
{% for item in items %} ... {% empty %} ... {% endfor %}Loop with empty fallback
{{ forloop.counter }} / {{ forloop.first }} / {{ forloop.last }}Loop counter variables
{% extends "base.html" %}Extend a base template
{% block content %} ... {% endblock %}Define a named block
{% include "partials/nav.html" %}Include a sub-template
{% include "card.html" with title=post.title %}Include with extra context
{% load static %} {% static "css/app.css" %}Load and use static files tag
{% csrf_token %}CSRF protection token (required in POST forms)
{% comment %} ... {% endcomment %}Template comment

Forms

from django.forms import ModelFormImport ModelForm
class PostForm(ModelForm): class Meta: model = Post; fields = ["title", "body"]ModelForm definition
form = PostForm(request.POST or None)Instantiate bound or unbound form
form = PostForm(request.POST, instance=post)Bind form to existing instance
form.is_valid()Validate submitted data
form.save()Save ModelForm to database
form.save(commit=False)Get model instance without saving
form.errorsDict of field validation errors
{{ form.as_p }}Render form fields wrapped in

tags

{{ form.title }} {{ form.title.errors }}Render individual field and errors
widgets = {"body": forms.Textarea(attrs={"rows": 5})}Customize field widget in Meta

Admin

from django.contrib import adminImport admin module
admin.site.register(Post)Register model with default admin
@admin.register(Post)Register model via decorator
class PostAdmin(admin.ModelAdmin): list_display = ["title", "created", "active"]Customize list view columns
list_filter = ["active", "created"]Add sidebar filters
search_fields = ["title", "body"]Enable search bar
prepopulated_fields = {"slug": ("title",)}Auto-populate slug from title
readonly_fields = ["created", "updated"]Make fields read-only in admin
ordering = ["-created"]Default ordering in list view
actions = ["make_active"]Register custom bulk actions

Settings & Middleware

INSTALLED_APPS = [..., "blog"]Register app in INSTALLED_APPS
DATABASES = {"default": {"ENGINE": "django.db.backends.postgresql", ...}}Database configuration
STATIC_URL = "/static/"; STATIC_ROOT = BASE_DIR / "staticfiles"Static files config
MEDIA_URL = "/media/"; MEDIA_ROOT = BASE_DIR / "media"Media files config
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"Default primary key field type
AUTH_USER_MODEL = "accounts.User"Custom user model setting
LOGIN_URL = "/login/"URL for login_required redirect
CACHES = {"default": {"BACKEND": "django.core.cache.backends.redis.RedisCache", "LOCATION": "redis://127.0.0.1:6379"}}Redis cache config
MIDDLEWARE = [..., "django.middleware.csrf.CsrfViewMiddleware"]Middleware stack order matters
from django.conf import settingsImport settings in code