Django from Basics to Production · APIs with Django REST Framework, and Production
The Deployment Checklist
Run Django's deployment checks, fix the settings they flag, and prepare static files, secrets and a production server.
What you'll build
You'll run manage.py check --deploy against development-style settings and production settings, and see exactly which security warnings disappear: debug mode, secret key, HSTS, secure cookies, HTTPS redirects and allowed hosts.
The idea
python manage.py check --deployinspects settings for common production mistakes.- Production needs:
DEBUG = False, a long randomSECRET_KEYfrom the environment,ALLOWED_HOSTS, HTTPS settings (SECURE_SSL_REDIRECT,SECURE_HSTS_SECONDS, secure cookies), andSECURE_PROXY_SSL_HEADERbehind a TLS-terminating proxy. - Serve with a production server (Gunicorn or uvicorn for ASGI), collect static files (
collectstatic, WhiteNoise or a CDN) and run migrations as a release step.
The code
import io
import re
import django
from django.conf import settings
base = dict(ROOT_URLCONF=__name__, INSTALLED_APPS=["django.contrib.contenttypes", "django.contrib.auth"],
MIDDLEWARE=["django.middleware.security.SecurityMiddleware"],
DATABASES={"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}})
urlpatterns = []
def deploy_check(**overrides):
from django.core.management import call_command
from django.core.management.base import SystemCheckError
for key, value in overrides.items():
setattr(settings, key, value)
out = io.StringIO()
try:
call_command("check", deploy=True, stdout=out, stderr=out)
except SystemCheckError as e:
out.write(str(e))
found = dict(re.findall(r"\(security\.(W\d+)\) ([^\n]+)", out.getvalue()))
return "\n".join(f" {code}: {msg[:70]}" for code, msg in sorted(found.items())) or " none"
settings.configure(**base, DEBUG=True, SECRET_KEY="dev")
django.setup()
print("development settings:\n" + deploy_check())
print("production settings:\n" + deploy_check(
MIDDLEWARE=["django.middleware.security.SecurityMiddleware", "django.middleware.csrf.CsrfViewMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware"],
DEBUG=False, SECRET_KEY="k" * 20 + "7Gq2#Lw9!vZ4^pR1&xN8$eT5@bY3*cM6",
ALLOWED_HOSTS=["shop.example.com"], SECURE_SSL_REDIRECT=True, SECURE_HSTS_SECONDS=31536000,
SECURE_HSTS_INCLUDE_SUBDOMAINS=True, SECURE_HSTS_PRELOAD=True, SESSION_COOKIE_SECURE=True,
CSRF_COOKIE_SECURE=True))
Output
development settings: W002: You do not have 'django.middleware.clickjacking.XFrameOptionsMiddlewar W003: You don't appear to be using Django's built-in cross-site request forg W004: You have not set a value for the SECURE_HSTS_SECONDS setting. If your W008: Your SECURE_SSL_REDIRECT setting is not set to True. Unless your site W009: Your SECRET_KEY has less than 50 characters, less than 5 unique charac W018: You should not have DEBUG set to True in deployment. W020: ALLOWED_HOSTS must not be empty in deployment. production settings: none
Run this on your computer — see “Get Started” for setup.
Common mistakes
- Running
manage.py runserverin production. - Committing
SECRET_KEYto Git, or reusing the development key. - HTTPS redirects behind a proxy without
SECURE_PROXY_SSL_HEADER, causing redirect loops. - Forgetting
collectstatic, so CSS and JS 404 whenDEBUGis off.
Key points
- Run
check --deployin CI and fix its warnings. - Secrets and hosts from the environment; HTTPS and secure cookies on.
- Production server, static files and migrations as part of the release.
Further reading: Deployment checklist · How to deploy with WSGI or ASGI
Practice questions
What does manage.py check --deploy do?
Answer
Runs Django's deployment system checks, warning about insecure settings such as DEBUG on, a weak SECRET_KEY, missing HSTS or insecure cookies.
Why set SECURE_PROXY_SSL_HEADER behind a load balancer?
Answer
TLS ends at the proxy, so Django sees HTTP; the header tells Django the original request was HTTPS, preventing redirect loops and insecure URL generation.
Where should SECRET_KEY come from in production?
Answer
From the environment or a secret manager, unique per deployment and never committed to version control.
Open in the app to mark lessons complete, take notes and track your progress.