djangodjango-middlewaredjango-3.2

Django 3.2.8 custom middleware returns 302 redirect errors


I am looking to use custom middleware to redirect a user to a their profile role if their profile role value is set to '0'.

Below is the current code I am using, but is causes a 302 redirect loop. This is based on other examples I found on the internet, but no luck in finding a fix.

Any ideas will be greatly valued.

from django.shortcuts import redirect
from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponseRedirect

class UserRoleMiddleware(MiddlewareMixin):
    def __init__(self, get_response):
        self.get_response = get_response

    def process_request(self, request):
        redirect_url = '/role/'

        if request.user.is_authenticated and request.user.profile.role == '0':
            print('user must define a role')
            return HttpResponseRedirect(redirect_url)

        return None

Response:

[23/Oct/2021 23:00:50] "GET /role/ HTTP/1.1" 302 0
user must define a role
[23/Oct/2021 23:00:50] "GET /role/ HTTP/1.1" 302 0
user must define a role
[23/Oct/2021 23:00:50] "GET /role/ HTTP/1.1" 302 0
user must define a role
[23/Oct/2021 23:00:50] "GET /role/ HTTP/1.1" 302 0

Solution

  • Because the middleware will also be triggered on your /role/ route, you should put in a check to see if the request path is for that route to avoid the loop.

        def process_request(self, request):
            redirect_url = '/role/'
    
            if request.path == redirect_url:
                return self.get_response(request)
    
            # or check for `and request.path != redirect_url` here
            if request.user.is_authenticated and request.user.profile.role == '0':
                print('user must define a role')
                return HttpResponseRedirect(redirect_url)
    
            return None
    
    

    Also, I believe you want to be returning self.get_response(request) not None.