Middleware

  • Explore Django Middleware and learn how to modify request and response cycles.
  • What is Middleware?

    Middleware is a layer between:

    Request (Browser → Django)
    Response (Django → Browser)

    It processes every request and response globally.

    Middleware can:

    • Modify request before view runs

    • Modify response before sending to user

    • Block requests

    • Add extra data

    • Perform logging, authentication, security

    Django Request–Response Cycle

    Browser Request

          ↓

    Middleware (Request Phase)

          ↓

    URL Dispatcher

          ↓

    View

          ↓

    Middleware (Response Phase)

          ↓

    Browser Response

    Why Middleware is Used?

    Purpose

    Example

    Authentication

    Check logged-in user

    Security

    Block IPs

    Logging

    Track user activity

    Performance

    Cache responses

    Custom rules

    Institute/project specific logic

    Built-in Django Middleware Examples

    Found in settings.py:

    MIDDLEWARE = [

        'django.middleware.security.SecurityMiddleware',

        'django.contrib.sessions.middleware.SessionMiddleware',

        'django.middleware.common.CommonMiddleware',

        'django.contrib.auth.middleware.AuthenticationMiddleware',

    ]

    These are executed top to bottom for requests
    Bottom to top for responses

    How Middleware Works Internally

    Each middleware is a Python class with:

    • __init__() → Runs once

    • __call__() → Runs on every request

    • Optional methods:

      • process_view()

      • process_exception()

      • process_template_response()

    Middleware Structure (Modern Django)

Basic Middleware Structure

class ExampleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # Code before view
        response = self.get_response(request)
        # Code after view
        return response
  • Description

    • get_response → Next middleware/view

    • Code before → request phase

    • Code after → response phase

    Custom Middleware

    What is Custom Middleware?

    Custom middleware is developer-defined logic that runs on every request.

    Examples:

    • Log user activity

    • Block unauthenticated users

    • Track request time

    • Restrict access by time/IP

    Steps to Create Custom Middleware

    Step 1. Create Middleware File

    your_app/

     ├── middleware.py

    Simple Request Logger Middleware

Request Logger Middleware

middleware.py

import datetime

class RequestLoggerMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        print(f"Request Path: {request.path}")
        print(f"Request Time: {datetime.datetime.now()}")

        response = self.get_response(request)

        return response
  • Description

    • Logs every request path

    • Executes before view runs

    Register Middleware in settings.py

    MIDDLEWARE = [

        'your_app.middleware.RequestLoggerMiddleware',

    ]

    Block Access for Anonymous Users

Login Required Middleware

middleware.py

from django.shortcuts import redirect

class LoginRequiredMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if not request.user.is_authenticated and request.path != '/login/':
            return redirect('/login/')
        return self.get_response(request)
  • Description

    • Checks authentication

    • Redirects to login if not logged in

    • Applies globally

    Use carefully (may affect admin/static files)

  • Execution Time Middleware

Request Execution Time Middleware

middleware.py

import time

class ExecutionTimeMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        start_time = time.time()
        response = self.get_response(request)
        end_time = time.time()

        print("Execution Time:", end_time - start_time)
        return response
  • IP Blocking Middleware

IP Restriction Middleware

middleware.py

from django.http import HttpResponseForbidden

BLOCKED_IPS = ['192.168.1.10']

class IPBlockMiddleware:

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        ip = request.META.get('REMOTE_ADDR')
        if ip in BLOCKED_IPS:
            return HttpResponseForbidden("Access Denied")
        return self.get_response(request)
  • Using process_view (Advanced)

Middleware with process_view

class ViewLoggerMiddleware:

    def process_view(self, request, view_func, view_args, view_kwargs):
        print("View Called:", view_func.__name__)
        return None
  • Runs before view execution

    Middleware Order (Very Important Concept)

    MIDDLEWARE = [

        'MiddlewareA',

        'MiddlewareB',

        'MiddlewareC',

    ]

    Execution:

    • Request: A → B → C

    • Response: C → B → A

    Middleware vs Decorator

    Middleware

    Decorator

    Global

    View-specific

    Runs for all requests

    Runs for selected views

    Applied in settings

    Applied in views