Django REST Framework & Deploy
Django REST Framework (DRF) is a powerful, flexible toolkit for building production-grade Web APIs on top of Django.
The 3 Core Building Blocks of DRF:
- Serializers (
ModelSerializer): Converts complex Django ORM model instances to native Python datatypes that can be rendered into JSON (and validates incoming JSON payloads back into models). - ViewSets (
ModelViewSet): Combines standard REST CRUD operations (list, create, retrieve, update, destroy) into a single unified class. - Routers (
DefaultRouter): Automatically generates all RESTful URL patterns (/api/products/,/api/products/1/) without writing manual path declarations!
# 1. Defining DRF Serializer: api/serializers.py
from rest_framework import serializers
from store_app.models import Product, Category
class ProductSerializer(serializers.ModelSerializer):
category_name = serializers.ReadOnlyField(source="category.name")
class Meta:
model = Product
fields = ["id", "title", "category", "category_name", "price", "stock", "is_active"]
# 2. Defining DRF ModelViewSet: api/views.py
from rest_framework import viewsets, permissions
from rest_framework.authentication import TokenAuthentication
class ProductViewSet(viewsets.ModelViewSet):
"""Provides complete CRUD REST endpoints automatically."""
queryset = Product.objects.filter(is_active=True).order_by("-created_at")
serializer_class = ProductSerializer
authentication_classes = [TokenAuthentication]
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
# 3. Automatic REST URL Routing: api/urls.py
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r"products", ProductViewSet, basename="product")
urlpatterns = router.urls
GET /api/products/-> List all productsPOST /api/products/-> Create productGET /api/products/42/-> Retrieve product #42PUT / PATCH /api/products/42/-> Update product #42DELETE /api/products/42/-> Delete product #42
Never use the built-in python manage.py runserver in production (it is single-threaded and not hardened for security). A production deployment uses a robust multi-tier architecture:
Production Deployment Checklist:
DEBUG = False: Never expose error traces in production.ALLOWED_HOSTS = ['yourdomain.com']: Prevents HTTP Host header attacks.- Environment Secrets (
.env): StoreSECRET_KEYandDATABASE_URLin environment variables. - Static Files with WhiteNoise: Enables Django to serve its own static files efficiently without separate storage servers.
# Production Settings Configuration (settings.py):
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
# 1. Load Secrets from Environment:
SECRET_KEY = os.getenv("DJANGO_SECRET_KEY", "fallback_local_key_not_for_prod")
DEBUG = os.getenv("DJANGO_DEBUG", "False") == "True"
ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "ourcompiler.com,127.0.0.1").split(",")
# 2. Production Security Headers:
SECURE_SSL_REDIRECT = not DEBUG
SESSION_COOKIE_SECURE = not DEBUG
CSRF_COOKIE_SECURE = not DEBUG
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
# 3. WhiteNoise Static Files Configuration:
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware", # Serves compressed static assets!
# ... standard middlewares ...
]
STATIC_ROOT = BASE_DIR / "staticfiles"
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
print("Production Settings Blueprint Configured.")
In production, start your app using: gunicorn my_project.wsgi:application --workers 4 --bind 0.0.0.0:8000. A general rule for worker count is (2 x CPU_Cores) + 1.
Hardcoding Django's SECRET_KEY exposes your application to session tampering and remote code execution vulnerabilities. Always use python-decouple or os.getenv() to load secrets from environment variables.
Write a simulated DRF serializer validate_price method that raises a ValidationError if price is less than or equal to zero.
def validate_price(price):
if price <= 0:
raise ValueError("Price must be a positive value greater than zero!")
return price
try:
print("Valid Price: ", validate_price(499.0))
print("Invalid Price:", validate_price(-10.0))
except ValueError as err:
print(f"Validation Error Caught: {err}")
Q What is the difference between Gunicorn and Uvicorn?
Gunicorn is a WSGI HTTP server for synchronous Python frameworks (Flask, standard Django). Uvicorn is an ASGI server for asynchronous Python frameworks (FastAPI, Django Channels).
Q What is JWT (JSON Web Token) authentication in DRF?
JWT is a stateless token format containing encrypted user claims. Unlike session cookies, the server does not need to query a database to verify JWT validity, making it ideal for distributed microservices.
Q What is WhiteNoise in Django?
WhiteNoise is a Python package that allows Django to serve its own static files (CSS, JS, images) with caching and Gzip/Brotli compression directly from the application server, without needing separate S3 buckets for small-to-medium deployments.