Среднее ПО в django продолжает перенаправлять, посещение сайта администратора невозможно

Я пишу проект на django, где мне нужно разделить страницы и аккаунты. Для этого я написал LoginCheckMiddleWare. Проблема в том, что я больше не могу зайти на сайт django-admin, потому что он продолжает перенаправлять меня. Я не знаю, что я сделал не так. У меня также есть файл EmailBackEnd.py, который я использую для входа в систему с помощью электронной почты, а не имени пользователя.

LoginCheckMiddleWare.py

from django.http.response import HttpResponseRedirect
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin


class LoginCheckMiddleWare(MiddlewareMixin):
    def process_view(self, request, view_func, view_args, view_kwargs):
        modulename = view_func.__module__
        user = request.user
        if user.is_authenticated:
            if user.user_type == '1':
                if modulename == 'user.views' or modulename == 'django.views.static':
                    pass
                elif modulename == 'user.log_views':
                    pass
                else:
                    return HttpResponseRedirect(reverse('user:admin_index'))

            elif user.user_type == '2':
                if modulename == 'instructor.views' or modulename == 'django.views.static':
                    pass
                elif modulename == 'user.log_views':
                    pass
                else:
                    return HttpResponseRedirect(reverse('instructor:instructor_index'))

            elif user.user_type == '3':
                if modulename == 'student.views' or modulename == 'django.views.static':
                    pass
                elif modulename == 'user.log_views':
                    pass
                else:
                    return HttpResponseRedirect(reverse('student:student_index'))
            else:
                return HttpResponseRedirect(reverse('user:login_user'))

        else:
            if request.path == reverse('user:login_user') or modulename == 'django.contrib.auth.views':
                pass
            else:
                return HttpResponseRedirect(reverse('user:login_user'))

EmailBackEnd.py

from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import get_user_model


class EmailBackEnd(ModelBackend):
    def authenticate(self, username=None, password=None, **kwargs):
        UserModel = get_user_model()
        try:
            user = UserModel.objects.get(email=username)
        except UserModel.DoesNotExist:
            return None
        else:
            if user.check_password(password):
                return user
        return None

log_views.py

from django.urls import reverse
from django.shortcuts import render
from django.http import HttpResponseRedirect
from user.EmailBackEnd import EmailBackEnd
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages


def login_user(request):
    if request.method == 'POST':
        user = EmailBackEnd.authenticate(request, username=request.POST.get(
            "email"), password=request.POST.get("password"))
        if user != None:
            login(request, user)
            if user.user_type == '1':
                return HttpResponseRedirect(reverse('user:admin_index'))
            elif user.user_type == '2':
                return HttpResponseRedirect(reverse('instructor:instructor_index'))
            else:
                return HttpResponseRedirect(reverse('student:student_index'))
        else:
            messages.error(request, 'Invalid Login Details')
            return HttpResponseRedirect(reverse('user:login_user'))
    return render(request, 'user/login.html')

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',
    'user.LoginCheckMiddleWare.LoginCheckMiddleWare',
]
AUTHENTICATION_BACKENDS = ['user.EmailBackEnd.EmailBackEnd']

urls.py

urlpatterns = [
path('', include('user.urls')),
path('admin/', admin.site.urls),
path('student/', include('student.urls')),
path('instructor/', include('instructor.urls')),
]

models.py

class CustomUser(AbstractUser):
    user_type_data = (
        (1, 'Admin'),
        (2, 'Instructor'),
        (3, 'Student')
    )
    user_type = models.CharField(
        max_length=20, choices=user_type_data, default=1)

Есть ли какие-нибудь предложения? Заранее большое спасибо

Атрибут user_type является целым числом, но вы делаете строковые сравнения в логике представления, поэтому ветвь else была выбрана везде, потому что 1 != '1' в Python. Взгляните на класс модели Django IntegerChoices, который создан именно для вашего случая использования.

Мы можем определить UserType модель:

class UserType(models.IntegerChoices):
    ADMIN = 1
    INSTRUCTOR = 2
    STUDENT = 3

И использовать его в параметре choices user_type:

class CustomUser(AbstractUser):
    user_type = models.CharField(
        max_length=20, choices=UserType.choices, default=UserType.ADMIN)

А также импортировать его в функции представления и использовать для сравнений:

class LoginCheckMiddleWare(MiddlewareMixin):
    def process_view(self, request, view_func, view_args, view_kwargs):
        modulename = view_func.__module__
        user = request.user
        if user.is_authenticated:
            if user.user_type == UserType.ADMIN:
                if modulename == 'user.views' or modulename == 'django.views.static':
                    pass
                elif modulename == 'user.log_views':
                    pass
                else:
                    return HttpResponseRedirect(reverse('user:admin_index'))

        ...

Это также делает ваш код более читабельным, поскольку использование UserType.ADMIN говорит читателю, что вы хотите сделать.

Вернуться на верх