Django Advanced Topics

Master advanced Django concepts including settings management, security, async views, Celery integration, testing, and production deployment strategies.

⚙️ Settings & Configuration

  • 20. How to Manage Django Settings for Multiple Environments?
    Use separate settings modules or environment-based configurations.
    # Option 1: Separate files
    settings/
    ├── base.py       # Common settings
    ├── dev.py        # Development
    ├── prod.py       # Production
    └── test.py       # Testing
    
    # dev.py
    from .base import *
    DEBUG = True
    ALLOWED_HOSTS = ['localhost']
    
    # prod.py
    from .base import *
    DEBUG = False
    ALLOWED_HOSTS = ['yourdomain.com']
    # Option 2: Use django-environ or python-decouple
    import environ
    env = environ.Env()
    environ.Env.read_env()
    
    DEBUG = env.bool('DEBUG', default=False)
    SECRET_KEY = env('SECRET_KEY')
    DATABASE_URL = env('DATABASE_URL')

🔒 Security

  • 21. How to Secure Django Applications?
    • Enable CSRF & XSS protection (enabled by default)
    • Use HTTPS (SSL/TLS) in production
    • Hide SECRET_KEY in environment variables
    • Validate and sanitize user inputs
    • Use secure password hashing (Django does this automatically)
    • Apply django-csp for Content Security Policy
    • Keep dependencies updated
    • Set proper CORS policies
    • Use SECURE_SSL_REDIRECT = True
    • Set SESSION_COOKIE_SECURE = True
    • Set CSRF_COOKIE_SECURE = True

🚀 Async & Celery

  • 31. How to Integrate Celery for Async Tasks in Django?
    # 1. Install Celery and Redis/RabbitMQ
    pip install celery redis
    
    # 2. Create celery.py in project root
    from celery import Celery
    import os
    
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
    app = Celery('myproject')
    app.config_from_object('django.conf:settings', namespace='CELERY')
    app.autodiscover_tasks()
    
    # 3. Define tasks
    from celery import shared_task
    
    @shared_task
    def send_email_task(email):
        # Send email logic
        print(f"Email sent to {email}")
        return True
    
    # 4. Call task
    send_email_task.delay('user@example.com')  # Async
    send_email_task.apply_async(args=['user@example.com'], countdown=60)  # Delay
  • 32. How to Make Async Views in Django (3.1+)?
    Define view with async def and use async ORM calls.
    from django.http import JsonResponse
    
    async def get_user(request, user_id):
        from .models import User
        user = await User.objects.aget(id=user_id)
        return JsonResponse({
            'id': user.id,
            'name': user.name
        })
    
    # Async ORM methods
    await Model.objects.aget()
    await Model.objects.acreate()
    await Model.objects.aupdate()
    await Model.objects.adelete()

📂 Static & Media Files

  • 34. What are Django Static and Media Files?
    Static files: CSS, JS, images → STATIC_URL, STATIC_ROOT
    Media files: User uploads → MEDIA_URL, MEDIA_ROOT
    # settings.py
    STATIC_URL = '/static/'
    STATIC_ROOT = BASE_DIR / 'staticfiles'
    STATICFILES_DIRS = [BASE_DIR / 'static']
    
    MEDIA_URL = '/media/'
    MEDIA_ROOT = BASE_DIR / 'media'
    
    # Collect static files for production
    python manage.py collectstatic

🔍 Raw SQL Queries

  • 35. How Do You Perform Raw SQL Queries in Django?
    # Method 1: raw()
    users = User.objects.raw('SELECT * FROM auth_user WHERE age > %s', [18])
    for user in users:
        print(user.name)
    
    # Method 2: cursor
    from django.db import connection
    
    with connection.cursor() as cursor:
        cursor.execute("SELECT COUNT(*) FROM auth_user")
        row = cursor.fetchone()
        print(row[0])

🧪 Testing

  • 37. How to Write Unit Tests in Django?
    Use Django's built-in test framework based on unittest.
    from django.test import TestCase, Client
    from .models import User
    
    class UserTest(TestCase):
        def setUp(self):
            self.user = User.objects.create(name='John', age=25)
        
        def test_user_creation(self):
            self.assertEqual(User.objects.count(), 1)
            self.assertEqual(self.user.name, 'John')
        
        def test_user_age(self):
            self.assertEqual(self.user.age, 25)
        
        def test_view(self):
            client = Client()
            response = client.get('/api/users/')
            self.assertEqual(response.status_code, 200)
    
    # Run tests
    python manage.py test

💾 Database Connection Pooling

  • 39. How Does Django Handle Database Connection Pooling?
    Through database backends (e.g., PostgreSQL) or external tools like pgbouncer. Django maintains persistent connections using CONN_MAX_AGE.
    # settings.py
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': 'mydb',
            'USER': 'myuser',
            'PASSWORD': 'mypass',
            'HOST': 'localhost',
            'PORT': '5432',
            'CONN_MAX_AGE': 600,  # Keep connections for 10 minutes
        }
    }

🚀 Production Deployment

  • 33. How to Structure Production Django Apps?
    • Use .env for secrets
    • Enable logging with proper log levels
    • Set DEBUG=False
    • Use Gunicorn or uWSGI as WSGI server
    • Configure Nginx as reverse proxy
    • Use PostgreSQL or MySQL (not SQLite)
    • Set proper ALLOWED_HOSTS
    • Enable security settings
    • Use Redis for caching
    • Configure static file serving
  • 40. How to Deploy Django in Production?
    # 1. Install dependencies
    pip install gunicorn psycopg2-binary
    
    # 2. Collect static files
    python manage.py collectstatic --noinput
    
    # 3. Run migrations
    python manage.py migrate
    
    # 4. Start Gunicorn
    gunicorn myproject.wsgi:application --bind 0.0.0.0:8000
    
    # 5. Nginx configuration
    server {
        listen 80;
        server_name yourdomain.com;
        
        location /static/ {
            alias /path/to/staticfiles/;
        }
        
        location /media/ {
            alias /path/to/media/;
        }
        
        location / {
            proxy_pass http://127.0.0.1:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
    Monitoring: Use Sentry for error tracking, Prometheus/Grafana for metrics