What Is a Django Middleware?

May 27, 2019

If you’ve created some sort of web application in django, chances are you’ve used a django middleware. Infact, django by includes some middleware to your web application by default. But what is a middleware? The django official documentation defines middleware as thus:

Middleware is a framework of hooks into Django’s request/response processing. It’s a light, low-level “plugin” system for globally altering Django’s input or output.

Understanding the concept of middleware in the Django request-response cycle

Let’s take a fairly familiar scenario. You’re hungry, so you place a phone call to order a box of pizza from your favourite fast food joint; Djangy’s Pizza. Your order is prepared and before you know it, delivered to your doorstep. This can be likened to a typical request-response cycle where the client (you) requests for a webpage (a box of pizza) on the internet.

But of course, you’re ordering from Djangy’s so there are a few things that go on behind the scenes. There are 2 points of interaction between you (the customer) and Djangy’s. The first is the phone call between you and the call attendant while the second is at the point of delivery. However, you’d probably agree that the only reason why any of this is happening in the first place is because you want some pizza. This is the prize; the resource. But in between when the call attendant takes your order and when the chef has prepared it, there are some basic events that may occur:

  • The call attendant verifies that the address exists and is within the delivery jurisdiction of the restaurant.
  • The call attendant saves your name, address, phone number, order and other information into a database.
  • The call attendant sends the order details to the chef to prepare

Similarly, after the pizza is prepared and before the order is delivered to you, there are a few things that may occur:

  • The pizza is put into a box.
  • A tag containing the order information is attached to the pizza box.
  • The order is assigned to a delivery person to make the delivery.

The above list of activities are to Djangy’s pizza what django middleware is to the django web framework. A middleware for example could be used to validate the headers of an http request to ensure requests come from a designated set of people, a bit like the call attendant verifying the validity of an address. You could also implement a django middleware to log all requests for easy debugging, like the call attendant saving order information to a database. A simplified version of this illustration is seen below.

Therefore, middleware is essentially a plugin that can be used to perform operations on the input data (request) before it gets to the view or the output data (response) after it has been processed by the view.

Django’s built-in middleware

Django comes shipped with some middleware to provide a “complete” web application. Here, we go over a few of them.

  • Common Middleware: This adds some nice-to-have functionality to the web application. It mainly helps with prepending “www” and appending “/” to input urls and forbids access to user agents based on the DISALLOWED_USER_AGENTS setting.
  • Message Middleware: This helps to handle temporary messages via cookies and session storage. It’s a very handy way to provide feedback in the form of messages to your users.
  • Security Middleware: This is where a few of django’s security features lie. Django provides settings that can be toggled on or off which enhances the security of your application. Some of these features include enforcing SSL redirect rules and HTTP Strict Transport Security.
  • Authentication Middleware: The authentication middleware adds the user attribute, representing the currently-logged-in user (or an AnonymousUser instance when no user is logged in), to every incoming HttpRequest object.

There are a number of other built-in middleware provided by Django, mostly performing a single specialised function. Hopefully by now you have an idea of the kind operations that can be carried out by middleware.

For a more detailed look into this, see Django’s built-in middleware reference

Using Django’s built-in Middleware

Using a built-in middleware in your web application is as simple as declaring a list of strings containing the full Python path to the middleware factory’s class or function name, assigning it to the MIDDLEWARE variable in your settings file. By default, django does this for you when you create an application using django-admin startproject making your setting look something like this:

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',
]

You can also add (or remove) middleware to the list. However, none of these settings are mandatory for your web application to function even though as you’ve seen above, they are very useful. Django also provides a means to create your own custom middleware.

Keep in mind that the middleware are executed ‘top-down’ from the first to the last, so position on the list matters. If Middleware B depends on Middleware A for example, it is important that Middleware A is before Middleware B on the list. The manger at Djangy’s wouldn’t expect an order to be sent to the chef if the customer’s address hasn’t been validated yet.

Using a django middleware is a great way to insert functionality with importance that can vary from nice-to-have to absolutely crucial and isn’t tied to your main application code.

comments powered by Disqus