All Articles Kinsa Creative

Django Middleware To Temporarily Redirect Every URL Except For One Single Page

There are other, possibly better ways to do this with .htaccess on an Apache server or via Nginx config, but in the case of a Heroku app for example, or to perhaps toggle a Django site into maintenance mode, Django middleware can be used to capture all inbound requests and dispatch or redirect them to a specific page. This works equally well to redirect offsite if necessary.

Add a test, for example in my_app/tests.py, add the following where 'my_page' is the named URL of the page that every other URL should redirect to; probably a maintenance page and 'home' is the named URL of a page on the site, for example the home page.

from django.test import Client, TestCase
from django.urls import reverse

class RedirectionMiddlewareTests(TestCase):
    def setUp(self) -> None:
        self.client = Client()
        self.redirects_to = reverse('my_page')

    def test_home_page(self):
        response = self.client.get(reverse('home'))
        self.assertEqual(response.status_code, 302)
        self.assertEqual(response.url, self.redirects_to)

Add a new file named middleware.py to the primary application, e.g. my_app. In that file add the following:

from django.shortcuts import reverse, redirect

class RedirectAppMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        path = request.META.get('PATH_INFO', '')

        if path != reverse('my_page'):
            response = redirect(reverse('my_page'))
            return response

        response = self.get_response(request)

        return response

In settings, add this middleware to the end of the middleware list:

MIDDLEWARE = [
    ...
    'my_app.middleware.RedirectAppMiddleware',
]

Feedback?

Email us at enquiries@kinsa.cc.