manage.py Commands
python manage.py runserverStart development server (port 8000)python manage.py runserver 0.0.0.0:8080Start server on custom host/portpython manage.py startproject mysiteCreate a new Django projectpython manage.py startapp blogCreate a new app within the projectpython manage.py makemigrationsGenerate migration files from model changespython manage.py migrateApply pending migrationspython manage.py migrate app 0003Migrate app to specific migrationpython manage.py showmigrationsList all migrations and their statuspython manage.py createsuperuserCreate admin user interactivelypython manage.py shellInteractive Python shell in project contextpython manage.py dbshellOpen database CLIpython manage.py testRun test suitepython manage.py test blog.tests.PostTestsRun specific test classpython manage.py collectstaticCollect static files to STATIC_ROOTpython manage.py checkCheck project for common problemspython manage.py flushDelete all data from databasepython manage.py loaddata fixtures.jsonLoad data from fixture filepython manage.py dumpdata blog > fixtures.jsonExport app data to fixtureModels
from django.db import modelsImport models moduleclass Post(models.Model):Define a modeltitle = models.CharField(max_length=200)String field with max lengthbody = models.TextField()Unbounded text fieldcreated = models.DateTimeField(auto_now_add=True)Auto-set timestamp on createupdated = models.DateTimeField(auto_now=True)Auto-set timestamp on saveactive = models.BooleanField(default=True)Boolean field with defaultuser = models.ForeignKey(User, on_delete=models.CASCADE)Foreign key with cascade deletetags = models.ManyToManyField(Tag, blank=True)Many-to-many relationshipprofile = models.OneToOneField(User, on_delete=models.CASCADE)One-to-one relationshipclass Meta: ordering = ["-created"]Default ordering for queriesdef __str__(self): return self.titleString representationdef get_absolute_url(self): return reverse("post-detail", args=[self.pk])Canonical URL for modelORM 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 recordsPost.objects.filter(title__icontains="django")Case-insensitive contains lookupPost.objects.filter(created__year=2024)Date field lookupPost.objects.exclude(active=False)Exclude matching recordsPost.objects.order_by("-created")Order descending by fieldPost.objects.values("id", "title")Return dicts instead of model instancesPost.objects.values_list("id", flat=True)Return list of single field valuesPost.objects.count()Count matching recordsPost.objects.first() / .last()Get first or last recordPost.objects.exists()Check if any matching records existPost.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 recordPost.objects.get_or_create(slug="hello", defaults={"title": "Hello"})Get or create recordPost.objects.update_or_create(slug="hello", defaults={"title": "Hello"})Update or create recordPost.objects.filter(active=True).update(views=0)Bulk updatePost.objects.filter(active=False).delete()Bulk deletefrom django.db.models import Q; Post.objects.filter(Q(title="x") | Q(body="x"))OR query with Q objectsViews
from django.shortcuts import render, get_object_or_404, redirectCommon view importsdef post_list(request): return render(request, "blog/list.html", {"posts": posts})Function-based viewget_object_or_404(Post, pk=pk)Get or raise Http404return redirect("post-list")Redirect by URL namereturn redirect(post.get_absolute_url())Redirect to model URLfrom django.views.generic import ListView, DetailView, CreateViewImport class-based viewsclass PostList(ListView): model = Post; template_name = "blog/list.html"ListView CBVclass PostDetail(DetailView): model = PostDetailView CBV (uses blog/post_detail.html)class PostCreate(CreateView): model = Post; fields = ["title", "body"]CreateView CBVfrom django.contrib.auth.decorators import login_requiredAuth decorator import@login_requiredRequire authentication for function viewfrom django.contrib.auth.mixins import LoginRequiredMixinAuth mixin for CBVfrom django.http import JsonResponse; return JsonResponse({"ok": True})Return JSON responseURL Configuration
from django.urls import path, includeImport URL utilitiespath("posts/", views.post_list, name="post-list")Basic URL patternpath("posts/<int:pk>/", views.post_detail, name="post-detail")URL with integer converterpath("posts/<slug:slug>/", views.post_detail, name="post-detail")URL with slug converterpath("blog/", include("blog.urls"))Include app-level URL confpath("blog/", include("blog.urls", namespace="blog"))Include with namespacefrom django.urls import reverse; reverse("post-detail", args=[pk])Reverse URL by name{% url "post-detail" post.pk %}Reverse URL in templatere_path(r"^legacy/(?P<id>\d+)/$", view)Regex URL patternTemplates
{{ 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 commentForms
from django.forms import ModelFormImport ModelFormclass PostForm(ModelForm): class Meta: model = Post; fields = ["title", "body"]ModelForm definitionform = PostForm(request.POST or None)Instantiate bound or unbound formform = PostForm(request.POST, instance=post)Bind form to existing instanceform.is_valid()Validate submitted dataform.save()Save ModelForm to databaseform.save(commit=False)Get model instance without savingform.errorsDict of field validation errors{{ form.as_p }}Render form fields wrapped in tags
{{ form.title }} {{ form.title.errors }}Render individual field and errorswidgets = {"body": forms.Textarea(attrs={"rows": 5})}Customize field widget in MetaAdmin
from django.contrib import adminImport admin moduleadmin.site.register(Post)Register model with default admin@admin.register(Post)Register model via decoratorclass PostAdmin(admin.ModelAdmin): list_display = ["title", "created", "active"]Customize list view columnslist_filter = ["active", "created"]Add sidebar filterssearch_fields = ["title", "body"]Enable search barprepopulated_fields = {"slug": ("title",)}Auto-populate slug from titlereadonly_fields = ["created", "updated"]Make fields read-only in adminordering = ["-created"]Default ordering in list viewactions = ["make_active"]Register custom bulk actionsSettings & Middleware
INSTALLED_APPS = [..., "blog"]Register app in INSTALLED_APPSDATABASES = {"default": {"ENGINE": "django.db.backends.postgresql", ...}}Database configurationSTATIC_URL = "/static/"; STATIC_ROOT = BASE_DIR / "staticfiles"Static files configMEDIA_URL = "/media/"; MEDIA_ROOT = BASE_DIR / "media"Media files configDEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"Default primary key field typeAUTH_USER_MODEL = "accounts.User"Custom user model settingLOGIN_URL = "/login/"URL for login_required redirectCACHES = {"default": {"BACKEND": "django.core.cache.backends.redis.RedisCache", "LOCATION": "redis://127.0.0.1:6379"}}Redis cache configMIDDLEWARE = [..., "django.middleware.csrf.CsrfViewMiddleware"]Middleware stack order mattersfrom django.conf import settingsImport settings in code