Introduction
Deploying Django in production requires more than just running python manage.py runserver. A production-grade Django application must be secure, scalable, maintainable, and fast. In this guide, we’ll explore the best practices for configuring your Django app for production, organizing your codebase, and optimizing for performance.
1. Production-Ready Configuration
Use Environment Variables
Avoid hardcoding secrets and environment-specific settings in your code. Use python-decouple or django-environ to manage environment variables.
from decouple import config
SECRET_KEY = config(‘SECRET_KEY’)
DEBUG = config(‘DEBUG’, cast=bool)
Set DEBUG = False
Always ensure DEBUG = False in production. With it enabled, Django will display detailed error pages that could leak sensitive information.
Configure ALLOWED_HOSTS
Set your domain name(s) or IP addresses in ALLOWED_HOSTS:
ALLOWED_HOSTS = [‘yourdomain.com’, ‘www.yourdomain.com’]
Static and Media Files
Use WhiteNoise or serve via CDN/Cloud Storage:
pip install whitenoise
MIDDLEWARE.insert(1, ‘whitenoise.middleware.WhiteNoiseMiddleware’)
STATICFILES_STORAGE = ‘whitenoise.storage.CompressedManifestStaticFilesStorage’
Secure Settings
- Set SECURE_HSTS_SECONDS, SECURE_SSL_REDIRECT, and use HTTPS.
- Use a strong password hashing algorithm like Argon2.
- Set SESSION_COOKIE_SECURE = True and CSRF_COOKIE_SECURE = True.
2. Code Architecture for Maintainability
Project Structure
A modular layout with separate Django apps for logically distinct functionality:
project_name/
├── apps/
│ ├── users/
│ ├── payments/
│ └── dashboard/
├── config/ # settings and wsgi/asgi
└── manage.py
Use Settings Modules
Split your settings.py into:
- base.py
- dev.py
- prod.py
Use environment variables to load the appropriate config file.
Custom User Model
Always use a custom user model from the start:
class User(AbstractUser):
# additional fields here
pass
DRY Principles
Use mixins, base templates, shared managers, and abstract models to keep your code DRY.
App Decoupling
Design apps with loose coupling and well-defined interfaces (e.g., services and signals).
3. Speed and Performance Optimization
Database Optimization
- Use select_related and prefetch_related to minimize queries.
- Add indexes to frequently queried fields.
- Use django-debug-toolbar in development to catch N+1 query problems.
Caching
- Use Memcached or Redis for caching views, templates, or per-object data.
- Cache database-heavy pages with @cache_page.
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
…
Query Optimization
Use values() or only() when you don’t need full model instances.
Background Tasks
Use Celery for offloading non-blocking tasks like sending emails or processing payments.
Asynchronous Views (Django 3.1+)
For IO-bound views, leverage Django’s async support:
async def my_async_view(request):
…
4. Logging and Monitoring
- Use Sentry, LogRocket, or Rollbar for error tracking.
- Configure Django’s built-in logging to write to files and/or external services.
LOGGING = {
‘version’: 1,
‘handlers’: {
‘file’: {
‘level’: ‘ERROR’,
‘class’: ‘logging.FileHandler’,
‘filename’: ‘/var/log/django/errors.log’,
},
},
‘loggers’: {
‘django’: {
‘handlers’: [‘file’],
‘level’: ‘ERROR’,
‘propagate’: True,
},
},
}
5. Deployment Checklist
- DEBUG = False
- Configure ALLOWED_HOSTS
- Use environment variables for secrets
- Enable HTTPS and HSTS
- Configure static and media file serving
- Use a production-ready WSGI/ASGI server (e.g., Gunicorn, Daphne, Uvicorn)
- Set up a process manager (e.g., Supervisor, systemd)
- Use a reverse proxy (e.g., Nginx or Traefik)
- Set up error logging and monitoring
- Configure database backups and migrations
- Perform load testing
- Harden security settings (e.g., cookies, CORS, permissions)
Final Thoughts
Deploying Django to production requires meticulous attention to both code structure and infrastructure. With the right configurations, optimized queries, caching, and deployment strategy, Django can perform at scale and power high-traffic web applications with ease. Whether you’re deploying your first project or scaling an existing one, following these best practices will keep your application fast, secure, and maintainable.
Need help with CI/CD for Django or integrating Docker? Stay tuned for the next guide in this series!