Middleware lets you run code before and after Django handles a web request. It helps you change requests or responses easily.
Request/response middleware flow 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 response = self.get_response(request) # Code after view return response
The __init__ method runs once when Django starts.
The __call__ method runs for each request, before and after the view.
Examples
Django
class SimpleMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): print('Before view') response = self.get_response(request) print('After view') 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 logs the URL path of each request and the status code of the response.
Django
class LogMiddleware: 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) print(f'Response status: {response.status_code}') return response
Important Notes
Middleware order matters: Django runs them in the order listed in MIDDLEWARE settings.
Middleware can modify both request and response objects.
Use middleware for cross-cutting concerns like logging, security, and headers.
Summary
Middleware runs code before and after views to handle requests and responses.
Define middleware as a class with __init__ and __call__ methods.
Middleware helps add features like logging, headers, and security checks easily.
Practice
1. What is the main purpose of middleware in Django's request/response flow?
easy
Solution
Step 1: Understand middleware role
Middleware runs code before and after views to modify requests or responses.Step 2: Compare options
Only To run code before and after the view processes a request describes this behavior; others describe unrelated tasks.Final Answer:
To run code before and after the view processes a request -> Option BQuick Check:
Middleware = pre/post view code [OK]
Hint: Middleware wraps views to add pre/post processing [OK]
Common Mistakes:
- Confusing middleware with template rendering
- Thinking middleware manages database directly
- Assuming middleware only handles authentication
2. Which of the following is the correct minimal structure of a Django middleware class?
easy
Solution
Step 1: Recall Django middleware class pattern
Middleware must have __init__ with get_response and __call__ with request.Step 2: Match options to pattern
Only class MyMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): response = self.get_response(request) return response matches this exact structure; others miss __call__ or use wrong methods.Final Answer:
Class with __init__ and __call__ methods -> Option CQuick Check:
Middleware class = __init__ + __call__ [OK]
Hint: Middleware class needs __init__ and __call__ methods [OK]
Common Mistakes:
- Using process_request instead of __call__
- Defining middleware as a simple function without class
- Missing get_response parameter in __init__
3. Given this middleware code, what will be printed when a request is processed?
class LogMiddleware:
def __init__(self, get_response):
self.get_response = get_response
print('Init called')
def __call__(self, request):
print('Before view')
response = self.get_response(request)
print('After view')
return response
# Assume this middleware is active and a request comes inmedium
Solution
Step 1: Understand middleware instantiation
__init__ runs once when server starts, printing 'Init called'.Step 2: Trace __call__ during request
On request, prints 'Before view', calls view, then prints 'After view'.Final Answer:
Init called\nBefore view\nAfter view -> Option AQuick Check:
Init once, then before/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 prints
- Ignoring that __call__ wraps the view call
4. Identify the error in this middleware code snippet:
class ExampleMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response
return responsemedium
Solution
Step 1: Check __call__ method
It assigns response = self.get_response without calling it (missing parentheses).Step 2: Understand consequence
Without parentheses, response is a function, not a response object, causing errors.Final Answer:
Missing parentheses when calling get_response in __call__ -> Option AQuick Check:
Call get_response() with () [OK]
Hint: Always call get_response with parentheses in __call__ [OK]
Common Mistakes:
- Forgetting parentheses on function calls
- Confusing method names
- Returning request instead of response
5. You want to add a custom header 'X-Hello: World' to every response using middleware. Which code correctly implements this?
hard
Solution
Step 1: Recall how to add headers in Django response
Response objects support dict-like access to headers: response['Header-Name'] = value.Step 2: Check options for correct header addition
class HeaderMiddleware: 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 uses response['X-Hello'] = 'World' correctly after calling get_response.Final Answer:
response['X-Hello'] = 'World' after getting the response -> Option DQuick Check:
Use response['Header'] = value to add headers [OK]
Hint: Add headers by setting response['Header'] = value after get_response [OK]
Common Mistakes:
- Trying to add headers to request object
- Using non-existent add_header method
- Accessing headers attribute which doesn't exist on response
