Django 1.10 added a new style of middleware with a different interface and a new setting called
MIDDLWARE instead of
MIDDLEWARE_CLASSES. Creating a class that supports both is easy enough with MiddlewareMixin, but that only works with Django 1.10 and above. What if you want to create middleware that can work with all versions of Django so it can be easily shared?
Writing a compatible middleware is not too hard. The trick is having a fallback for when the import fails on any earlier versions of Django. I couldn’t find a full example anywhere and it took me a few attempts to get it just right, so I thought I’d share my results to save you some time.
import os from django.core.exceptions import MiddlewareNotUsed from django.shortcuts import redirect try: from django.utils.deprecation import MiddlewareMixin except ImportError: MiddlewareMixin = object class CompatibleMiddleware(MiddlewareMixin): def __init__(self, *args, **kwargs): if os.getenv('DISABLE_MIDDLEWARE'): raise MiddlewareNotUsed('DISABLE_MIDDLEWARE is set') super(CompatibleMiddleware, self).__init__(*args, **kwargs) def process_request(self, request): if request.path == '/': return redirect('/hello') def process_response(self, request, response): return response
CompatibleMiddleware can now be used in both
MIDDLEWARE_CLASSES. It should also work with any version of Django so it’s easier to share.