Write Custom Django Middleware

django middleware

Hello Techies,

In this blog, we will discuss the use of Django middleware with a practical example.

Middleware is a regular class of Python that hooks into Django’s request / response life cycle.

There are 2 types of Django middleware :

  • Built-in middleware
  • Custom middleware

Built-in middleware

Django provides built-in middleware classes.

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Each middleware component is responsible for performing certain tasks.

During the request cycle, middleware classes run top-down, first Security middleware, then SessionMiddleware until XframeOptions middleware.

During the response cycle, the middleware classes run bottom-up, meaning they will run up to XframeOptionMidalware, then MessageMidalware, Security Middleware.

So this is some basic information about the Built-in middleware.


How Django Middleware Works:

Let’s look at an example, when a user sends a request to the server, that request goes through the middleware between the user and the server. The same process is performed when a response is sent to a user. This situation may change in some cases, such as middleware may also response to the user.

Check the below images with different scenarios:

How requests and responses work between user and server.

How to activate Django Middleware:

  • To activate any middleware, add it to the MIDDLEWARE_CLASS list in your Django settings.
  • In the MIDDLEWARE class, each middleware component is represented with a full Python path to the middleware function name or class.
  • The middleware order is matters because a middleware can depend on other middleware.

Function-Based Django Middleware

  • A middleware factory is a callable one that takes the called get_response and returns a middleware.
  • Just like a view, the middleware takes a request and returns the response.

Syntax:

def my_middleware(get_response):
    # one-time configuration and initialization.
    def my_function(request):
        # Code executed for each request before view
. 
        response = get_response(request)
        # Code executed for each request/response after view.
        return response
    return my_function

get_response():

  • This might be the actual view or it might be the next middleware in the chain.
  • Current middleware doesn’t need to know or care exactly what it is, it just represents what comes next.

Let’s check one function based middleware example.

Create a middleware file where we will add our all middleware function.

def middleware_name(get_response):
    print("One Time initialization")
    # write your code as per your requirement
    def middleware_func(request):
        print("Before View")
        # this code will work before view
        # write your code as per your requirement
        response = get_response(request)
        print("After view")
        # this code will work after view
        # write your code as per your requirement
        return response
    return middleware_func

You can add multiple middleware as per your requirements and then add it to MIDDLEWARE_CLASS in setting.py file.

Add the file path to the middleware class in the setting.py file.

# settings.py

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'app.middlewares.middleware_name'
]

That’s it now you can check how this middleware will work.

Class-Based Django Middleware

Syntax:

class Middleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # one time configuration and initialization.
    def __call__(self, request):
        # Code executed for each request before view
.
        response = self.get_response(request)
        # Code executed for each request/response after view.
        return response 

__init__(get_response):

  • __init__(get_response) – Middleware factories must accept a get_response arguments.
  • Django initializes middleware with only the get_response argument.

Let’s check one Class-based middleware example.

Create a middleware file where we will add our all middleware function.

class MiddlewareName:
    def __init__(self, get_response):
        self.get_response = get_response
        print("One Time initialization: class view")

    def __call__(self, request):
        print("Before View: class view")
        # This code will work before view
        # write your code as per your requirement
        response = self.get_response(request)
        # This code will work after view
        # write your code as per your requirement
        print("After view: class view")
        return response

You can add multiple middlewares as per your requirements and then add it to MIDDLEWARE_CLASS in the setting.py file.

Add the file path to the middleware class in the setting.py file.

# settings.py

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'app.middlewares.MiddlewareName'
]

That’s it now you can check how this middleware will work.

I hope you understand how to write custom Django middleware. See the official site for more information about Django Middleware.

Leave a Comment