Django

HTTPS Redirect in Django

Django has a built-in setting specifically for this, avoiding the need for custom middleware or server-level rules for the redirect logic itself.

# settings.py
SECURE_SSL_REDIRECT = True

With this enabled, Django's SecurityMiddleware automatically redirects any plain HTTP request to its HTTPS equivalent. It needs SecurityMiddleware present in MIDDLEWARE, which is included by default in new Django projects.

The proxy header caveat

If Django is running behind Nginx or another reverse proxy (the typical production setup), Django itself sees every request as plain HTTP even when the original visitor connection was HTTPS, since TLS terminated at the proxy. You need to also set SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') so Django correctly reads the proxy's forwarded-protocol header — skipping this causes an infinite redirect loop, the most common issue people hit with this setting.

Why SECURE_PROXY_SSL_HEADER is easy to forget and hard to debug without it

SECURE_SSL_REDIRECT alone works correctly for a Django app receiving direct HTTPS connections, but fails silently into a redirect loop the moment a reverse proxy is introduced, since Django then sees every request as plain HTTP — the fix, adding SECURE_PROXY_SSL_HEADER, isn't obvious from the error behavior alone, which is why this specific gotcha catches many developers deploying behind Nginx for the first time.

What other security settings Django bundles alongside SECURE_SSL_REDIRECT

Django's security middleware also offers SESSION_COOKIE_SECURE and CSRF_COOKIE_SECURE settings, ensuring cookies are only ever sent over HTTPS connections — enabling these alongside SECURE_SSL_REDIRECT rounds out a genuinely complete HTTPS enforcement rather than just handling the initial redirect.

What order to add these settings in in your settings.py file

While Django doesn't strictly require a specific ordering, grouping SECURE_SSL_REDIRECT, SECURE_PROXY_SSL_HEADER, and the related cookie security settings together in your settings file makes the HTTPS enforcement configuration easier to review and maintain as a coherent block rather than scattered individually throughout the file.

What Django's deployment checklist command reveals about your HTTPS configuration

Running Django's manage.py check --deploy command surfaces warnings about several security-related settings, including SECURE_SSL_REDIRECT if it's not enabled, functioning as a useful automated pre-deployment checklist rather than manually reviewing settings.py for every relevant setting.

How this setting interacts with Django REST Framework API endpoints specifically

SECURE_SSL_REDIRECT applies uniformly across your entire Django application, including any REST Framework API endpoints, meaning API clients also need to correctly handle the redirect or connect via HTTPS directly from the start — worth confirming any API client libraries you control are configured accordingly.

Why local development settings should typically disable this setting entirely

Local development typically runs over plain HTTP without a certificate at all, meaning SECURE_SSL_REDIRECT should be explicitly disabled in your development settings file to avoid an unwanted redirect loop during local testing, while remaining enabled in your production settings.

A closing recommendation for Django deployments specifically

Running Django's deployment check command as a standard step in your deployment pipeline, not just once during initial setup, catches configuration drift early if a future settings change accidentally disables or misconfigures HTTPS enforcement.

What Django REST Framework specifically adds to this configuration picture

Django REST Framework builds on top of Django's core request handling, meaning SECURE_SSL_REDIRECT and SECURE_PROXY_SSL_HEADER apply to DRF-powered API endpoints exactly as they would to standard Django views, with no separate DRF-specific HTTPS configuration required.

How this setting interacts with Django's ALLOWED_HOSTS configuration

SECURE_SSL_REDIRECT and ALLOWED_HOSTS serve distinct purposes — ALLOWED_HOSTS validates which hostnames Django will respond to at all, while SECURE_SSL_REDIRECT controls protocol enforcement for those already-permitted hosts — both need correct, independent configuration for a fully secure Django deployment.