SyntaxStudy
Sign Up
Django Preparing Django for Production
Django Beginner 1 min read

Preparing Django for Production

Deploying Django to production requires several configuration changes from the development defaults. The most critical is setting DEBUG = False, which disables the detailed error page (which leaks source code and settings) and enables Django's 404 and 500 error templates. The SECRET_KEY must be a long random string kept secret and loaded from an environment variable, never hardcoded in settings.py. The ALLOWED_HOSTS setting must list every hostname and IP address that Django will serve. With DEBUG = False Django rejects requests with a Host header not in this list, protecting against HTTP Host header attacks. In production you also need to configure SECURE_SSL_REDIRECT, SESSION_COOKIE_SECURE, CSRF_COOKIE_SECURE, and SECURE_HSTS_SECONDS to enforce HTTPS and prevent session hijacking. Static files require special handling in production. Running python manage.py collectstatic gathers all static files from each app into the STATIC_ROOT directory. In production, a dedicated web server (Nginx) or a cloud storage service (Amazon S3 via django-storages) serves these files directly, bypassing Django. WhiteNoise is a popular alternative that lets Django serve static files efficiently without Nginx configuration changes.
Example
# mysite/settings/production.py — production settings
import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent.parent

# Load sensitive values from environment
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']
DEBUG      = False

ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '').split(',')

# Database — PostgreSQL in production
DATABASES = {
    'default': {
        'ENGINE':   'django.db.backends.postgresql',
        'NAME':     os.environ['DB_NAME'],
        'USER':     os.environ['DB_USER'],
        'PASSWORD': os.environ['DB_PASSWORD'],
        'HOST':     os.environ.get('DB_HOST', 'localhost'),
        'PORT':     os.environ.get('DB_PORT', '5432'),
    }
}

# HTTPS security headers
SECURE_SSL_REDIRECT         = True
SESSION_COOKIE_SECURE       = True
CSRF_COOKIE_SECURE          = True
SECURE_HSTS_SECONDS         = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD         = True
SECURE_BROWSER_XSS_FILTER   = True
X_FRAME_OPTIONS             = 'DENY'

# Static and media files
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATIC_URL  = '/static/'
MEDIA_ROOT  = BASE_DIR / 'media'
MEDIA_URL   = '/media/'

# Caching — Redis in production
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.redis.RedisCache',
        'LOCATION': os.environ.get('REDIS_URL', 'redis://127.0.0.1:6379/1'),
    }
}