Среднее ПО в 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 говорит читателю, что вы хотите сделать.