Middleware helps Django handle tasks before and after a web request. It makes your app smarter and easier to manage.
Why middleware matters 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, letting you add code 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'Received request: {request.path}') response = self.get_response(request) print(f'Sent response with status: {response.status_code}') return response
Important Notes
Middleware runs in the order listed in settings.MIDDLEWARE.
Middleware can change requests and responses, so use it carefully.
Always return the response object from your middleware.
Summary
Middleware lets you add code before and after views run.
It helps with tasks like logging, security, and modifying responses.
Middleware makes your Django app easier to manage and extend.
Practice
1. What is the main purpose of middleware in a Django application?
easy
Solution
Step 1: Understand middleware role
Middleware acts on requests and responses before and after views run.Step 2: Compare options to middleware function
Only To process requests and responses globally before reaching views describes processing requests and responses globally, which matches middleware's purpose.Final Answer:
To process requests and responses globally before reaching views -> Option AQuick Check:
Middleware = global request/response processing [OK]
Hint: Middleware acts on requests/responses before views [OK]
Common Mistakes:
- Confusing middleware with models or templates
- Thinking middleware only handles authentication
- Assuming middleware runs after views only
2. Which of the following is the correct way to add a custom middleware class in Django's settings?
easy
Solution
Step 1: Identify where middleware is configured
Django uses the MIDDLEWARE list in settings.py to register middleware classes.Step 2: Match the correct setting for middleware
Only Add 'myapp.middleware.MyMiddleware' to MIDDLEWARE list in settings.py correctly adds the middleware class path to the MIDDLEWARE list.Final Answer:
Add 'myapp.middleware.MyMiddleware' to MIDDLEWARE list in settings.py -> Option BQuick Check:
Middleware goes in MIDDLEWARE list [OK]
Hint: Middleware classes go in MIDDLEWARE list, not INSTALLED_APPS [OK]
Common Mistakes:
- Adding middleware to INSTALLED_APPS instead of MIDDLEWARE
- Placing middleware in TEMPLATES or DATABASES settings
- Using incorrect string format for middleware path
3. Given this middleware code snippet, what will be printed when a request is processed?
class LogMiddleware:
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 responsemedium
Solution
Step 1: Analyze __call__ method flow
The middleware prints 'Before view', calls the view via get_response, then prints 'After view'.Step 2: Understand order of prints
'Before view' prints before the view runs, 'After view' prints after the view returns.Final Answer:
Before view printed before the view runs, After view printed after -> Option AQuick Check:
Middleware prints before and after view [OK]
Hint: Middleware __call__ runs code before and after get_response [OK]
Common Mistakes:
- Thinking only one print runs
- Confusing order of prints
- Assuming middleware skips printing
4. You wrote this middleware but it causes an error:
class ErrorMiddleware:
def __init__(self, get_response):
pass
def __call__(self, request):
return self.get_response(request)
What is the problem?medium
Solution
Step 1: Check __init__ method implementation
The __init__ method ignores get_response and does not save it as self.get_response.Step 2: Understand __call__ method usage
__call__ tries to call self.get_response, but it does not exist, causing an AttributeError.Final Answer:
The __init__ method does not save get_response, causing AttributeError -> Option CQuick Check:
Save get_response in __init__ to avoid errors [OK]
Hint: Always save get_response in __init__ as self.get_response [OK]
Common Mistakes:
- Not storing get_response in __init__
- Assuming __call__ doesn't need to return response
- Thinking middleware must inherit from a base class
5. You want to create middleware that adds a custom header
X-App-Version with value 1.0 to every response. Which code snippet correctly implements this?hard
Solution
Step 1: Identify where to add headers in middleware
Headers must be added to the response object after the view runs, inside __call__.Step 2: Check each option's method
class VersionMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): response = self.get_response(request) response['X-App-Version'] = '1.0' return responsecorrectly adds the header after calling get_response and returns the modified response.Final Answer:
correctly adds the header in __call__ after response creation -> Option DQuick Check:
Add headers after get_response in __call__ [OK]
Hint: Modify response headers after get_response call in __call__ [OK]
Common Mistakes:
- Trying to add headers to request instead of response
- Using process_request which can't modify response
- Not returning the response object
