Security isn't a feature — it's a requirement. Django provides excellent security defaults, but there are still important steps you need to take before deploying to production.
Start with the basics: set DEBUG=False, configure ALLOWED_HOSTS, and ensure SECRET_KEY is truly secret and unique per environment. These three settings alone prevent the most common Django security mistakes.
For authentication, use Django's built-in auth system. Enable password validation, implement rate limiting on login endpoints, and always hash passwords with the default PBKDF2 hasher (or upgrade to Argon2).
CSRF protection is enabled by default, but make sure you're using the {% csrf_token %} tag in every POST form and the X-CSRFToken header for AJAX requests. For HTMX, set hx-headers on the body tag.
HTTP security headers make a big difference. Configure Content-Security-Policy, X-Content-Type-Options, X-Frame-Options, and Strict-Transport-Security. Django's SecurityMiddleware handles most of these with simple settings.
Finally, keep your dependencies updated. Use pip-audit or Safety to scan for known vulnerabilities, and set up Dependabot or Renovate for automated dependency updates.