How to Set Up Custom Middleware in Django?
Last Updated :
04 Oct, 2024
One of the key and must feature of Django is the concept of middleware, which allows us to process requests and responses across the entire web application. Middleware in Django acts as a layer between the requests and view or between the view and the response, including it's useful for tasks like logging, authentication, modifying headers, etc.
In this article we are going to deep dive into the knowledge of custom middleware in Django.
Understanding Middleware in Django
MiddleWare in Django is a light-weight, modular with low-level of "plugin" dependencies that processes requests and responses globally across our application. It is activated whenever we a request flows through the application, making it powerful tool for cross-cutting concerns such as:
- Requests/ Responses logging to log files.
- Authentication and authorization
- Session Management
- Performance optimization
- Content filtering.
In Django, middleware is a python class which is executed as follows:
- Request Phase: This is the time before the view is called.
- Response Phase: After the view has been processed but before the response is returned to the client again.
How Django Middleware Works:
- A Request comes into the system, device or server from a user.
- Before reaching to the view Middleware processes this request.
- The view processes the request and returns the response.
- Middleware have the power to change this response before it is sent back to the user.
Creating Custom Middleware
To create a custom middleware in Django it involves writing a python class which implements at least one of the following methods.
- __init__(): This is responsible for initializing the middleware once, whenever the server starts.
- __call__(): It process the request and response.
- process_request(self, request): Before a view is called; this can able to modify or even return a response.
- process_response(self, request, response): After the view is called; this can modify or even return a new response.
Basic Structure of Custom Middleware:
Python
class MyCustomMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time initialization
def __call__(self, request):
# Code to be executed for each request
# before the view (request phase)
response = self.get_response(request)
# Code to be executed for each response
# after the view is called (response phase)
return response
Set Up a Custom Middleware in Django
For this article particularly, we are going to create a middleware which is going to log the time how much a request takes to process, which is useful for performance monitoring.
Prerequisites
pip install django
django-admin startproject middleware_project
cd middleware_project
python manage.py startapp myapp
Step 1: Create a Custom Middleware File
In myapp/middleware/request_time_logging.py, add the following middleware.
Python
import time
class RequestTimeLoggingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# One-time configuration and initialization
def __call__(self, request):
# Start time recording before the view is called
start_time = time.time()
# Get the response from the view
response = self.get_response(request)
# End time recording after the view has processed the request
duration = time.time() - start_time
print(f"Request processed in {duration:.4f} seconds")
return response
Step 2 - Add Middleware to settings.py
In middleware_project/settings.py
Python
# ..
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.middleware.common.CommonMiddleware',
# Add your custom middleware
'myapp.middleware.request_time_logging.RequestTimeLoggingMiddleware',
]
Step 3 - Create a simple view to Test the Middleware
myapp/views.py
Python
from django.http import HttpResponse
def home(request):
return HttpResponse("Hello, this is the home page!")
Step 4 - Configuring URL Routing
Now, we set up the URL routing for the view in myapp/urls.py:
Python
from django.urls import path
from .views import home
urlpatterns = [
path('', home, name='home'),
]
Next, similarly we include myapp's URLs in the main project's urls.py(middleware_project/urls.py)
Python
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
# Include the app's URLs
path('', include('myapp.urls')),
]
Step 5 - Run the Django Developement Server
Now that the middleware and view are set up done, we can run the server and see the middleware in action
Run the Server:
python manage.py runserver
Web Output:
Web OutputConsole Output:
Console OutputEach time we refresh the browser we get the log of the time taken to processs the output
Best Practice to Create and Manage Middleware in Django
With Great power comes Great responsibiliity, while middleware is powerful, but to handle this we must take several best practices which maintain the flow of developement process keeping in mind like a production grade applications.
1) Keep Middleware Lightweight
Middleware though is the powerful way used for logging, authentication, authorization etc., we must need to keeo them as light as possible beacause for every execution they need to do request and response, so it is crucial to avoid performance heavy tasks inside.
2) Handle Exceptions Gracefully
Make sure our middleware must able to handle all exceptions ny mantaining integrity. This is especially important if our middleware is modifying the request or response as per the execution requirements.
3) Order Matters
Middleware is executed in the order it is listed in Middleware, means one by one linearly, we always be careful of this when defining custom middleware, as it can affect how different middleware component interacts.
4) Ensure Reusablitiy
We must keep our middleware resuable by making it as modular as possible by every means. This will allow us to use it across different projects.
5. Limit Dependency on the Request Object
Although we can able to modify the request object in middleware, it is generally advisable to maintain it's original structure for consistency, easy maintainenece and reliabilty in views.
Conclusion
We finally created a Django Project with the usage of custom middleware that logs the time takes to process each request. This is a powerful way to monitor the performance of the web app created using Django which helps in handling the cross-cutting concerns such as logging, authentication, or security checks across all views.
Similar Reads
How to create custom middleware in express ? Express.js is the most powerful framework of the node.js. Express.js is a routing and Middleware framework for handling the different routing of the webpage, and it works between the request and response cycle. Express.js use different kinds of middleware functions in order to complete the different
2 min read
Middleware in Django Middleware is a series of processing layers present between the web server and the view (controller in some frameworks), allowing the user to intercept, modify, and add behavior to these requests and responses.What is Middleware in Django?In Python Django, middleware is a framework that provides a m
9 min read
How to Render Data in Django Django's render() function is a fundamental tool for building dynamic web applications. It simplifies the process of combining HTTP requests with HTML templates and dynamic data, making it easier for developers to create interactive and data-driven web pages. What is render()?In Django, the render(
3 min read
How To Implement ChatGPT In Django Integrating ChatGPT into a Django application allows you to create dynamic and interactive chat interfaces. By following the steps outlined in this article, you can implement ChatGPT in your Django project and provide users with engaging conversational experiences. Experiment with different prompts,
4 min read
How to Create a Basic Project using MVT in Django ? Prerequisite - Django Project MVT Structure Assuming you have gone through the previous article. This article focuses on creating a basic project to render a template using MVT architecture. We will use MVT (Models, Views, Templates) to render data to a local server. Create a basic Project: To in
2 min read