Middleware lets you add extra steps to handle web requests and responses. Custom middleware helps you add your own special rules or actions in your Django app.
Creating custom middleware in Django
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
Django
class MyMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # Code before view runs response = self.get_response(request) # Code after view runs return response
The __init__ method runs once when the server starts.
The __call__ method runs for each request.
Examples
Django
class SimpleLogMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): print(f"Request path: {request.path}") response = self.get_response(request) return response
Django
class AddHeaderMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): response = self.get_response(request) response["X-Custom-Header"] = "Hello" return response
Sample Program
This middleware measures how long each request takes and prints it in the console.
Django
import time class TimerMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): start = time.time() response = self.get_response(request) duration = time.time() - start print(f"Request took {duration:.4f} seconds") return response
Important Notes
Always add your custom middleware class to the MIDDLEWARE list in settings.py.
Middleware runs in the order listed in MIDDLEWARE.
Be careful with code in middleware to avoid slowing down requests.
Summary
Middleware lets you run code before and after views.
Custom middleware is a class with __init__ and __call__ methods.
Add your middleware to MIDDLEWARE in settings to activate it.
Practice
1. What is the main purpose of custom middleware in Django?
easy
Solution
Step 1: Understand middleware role
Middleware runs code before and after views handle requests.Step 2: Compare options
Only To run code before and after a view processes a request describes middleware's purpose correctly; others describe unrelated tasks.Final Answer:
To run code before and after a view processes a request -> Option AQuick Check:
Middleware = pre/post view code [OK]
Hint: Middleware runs code around views, not models or templates [OK]
Common Mistakes:
- Confusing middleware with models or templates
- Thinking middleware only handles authentication
- Believing middleware runs only after views
2. Which method must a Django custom middleware class implement to process requests and responses?
easy
Solution
Step 1: Recall middleware class structure
Custom middleware uses __init__ for setup and __call__ to handle requests and responses.Step 2: Identify correct method for processing
__call__ is the method that processes requests and responses; others are incorrect or deprecated.Final Answer:
__call__ -> Option AQuick Check:
Middleware processing method = __call__ [OK]
Hint: Use __call__ to process requests in custom middleware [OK]
Common Mistakes:
- Using process_request which is old style
- Confusing __init__ with request processing
- Inventing non-existent methods like handle_request
3. Given this middleware code, what will be printed when a request is processed?
class SimpleMiddleware:
def __init__(self, get_response):
self.get_response = get_response
print('Middleware initialized')
def __call__(self, request):
print('Before view')
response = self.get_response(request)
print('After view')
return response
medium
Solution
Step 1: Understand when __init__ runs
__init__ runs once when middleware is created, printing 'Middleware initialized'.Step 2: Trace __call__ execution order
__call__ prints 'Before view', calls the view, then prints 'After view'.Final Answer:
Middleware initialized\nBefore view\nAfter view -> Option BQuick Check:
Init then before and after view prints [OK]
Hint: Init prints once; __call__ prints before and after view [OK]
Common Mistakes:
- Thinking __init__ runs on every request
- Mixing order of print statements
- Ignoring that __call__ wraps the view call
4. What is wrong with this custom middleware code?
class MyMiddleware:
def __init__(self):
pass
def __call__(self, request):
response = self.get_response(request)
return response
medium
Solution
Step 1: Check __init__ signature
Middleware __init__ must accept get_response parameter to store it for later use.Step 2: Identify missing attribute
get_response is used in __call__, but not saved in __init__, causing an error.Final Answer:
Missing get_response parameter in __init__ -> Option CQuick Check:
__init__ needs get_response [OK]
Hint: Always accept get_response in __init__ for middleware [OK]
Common Mistakes:
- Omitting get_response parameter
- Not storing get_response as instance variable
- Thinking __call__ cannot return response
5. You want to create a custom middleware that adds a header 'X-Hello: World' to every response. Which code snippet correctly implements this?
hard
Solution
Step 1: Confirm __init__ accepts get_response
class HelloMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): response = self.get_response(request) response['X-Hello'] = 'World' return response correctly accepts and stores get_response in __init__.Step 2: Check __call__ modifies response
class HelloMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): response = self.get_response(request) response['X-Hello'] = 'World' return response calls get_response, adds header, and returns response properly.Step 3: Identify errors in other options
class HelloMiddleware: def __init__(self): pass def __call__(self, request): response = self.get_response(request) response.headers.add('X-Hello', 'World') return response misses get_response in __init__; class HelloMiddleware: def __call__(self, request): response = self.get_response(request) response['X-Hello'] = 'World' return response misses __init__; class HelloMiddleware: def __init__(self, get_response): self.get_response = get_response def process_response(self, request, response): response['X-Hello'] = 'World' return response uses old process_response method not supported in new style middleware.Final Answer:
class HelloMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): response = self.get_response(request) response['X-Hello'] = 'World' return response -> Option DQuick Check:
New middleware = __init__ + __call__ + modify response [OK]
Hint: New middleware needs get_response in __init__ and modifies response in __call__ [OK]
Common Mistakes:
- Omitting get_response in __init__
- Using old process_response method
- Trying to add headers before calling get_response
