[英]Middleware in django keeps redirecting, visiting admin-site not possible
I am writing a django project where I need to separate the pages and the accounts.我正在编写一个 django 项目,我需要将页面和帐户分开。 Do to so, I wrote a LoginCheckMiddleWare.
为此,我写了一个LoginCheckMiddleWare。 The problem is that I am not able to visit the django-admin site anymore, because it keeps redirecting me.
问题是我无法再访问 django-admin 站点,因为它一直在重定向我。 I don't what I did wrong.
我不知道我做错了什么。 I also have an EmailBackEnd.py file, that I use for logging in with the email and not the username.
我还有一个 EmailBackEnd.py 文件,用于使用 email 而不是用户名登录。
LoginCheckMiddleWare.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电子邮件后端.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日志视图.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设置.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网址.py
urlpatterns = [
path('', include('user.urls')),
path('admin/', admin.site.urls),
path('student/', include('student.urls')),
path('instructor/', include('instructor.urls')),
]
models.py模型.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)
Any suggestion?有什么建议吗? Thank you very much in advance
非常感谢您提前
The user_type
attribute is an integer, but you are making string comparisons in the view logic, so the else
branch has been selected everywhere because 1 != '1'
in Python. user_type
属性是 integer,但您正在视图逻辑中进行字符串比较,因此到处都选择了else
分支,因为 Python 中1 != '1'
。 Have a look at Django's IntegerChoices model class, which is created exactly for your use case.看看 Django 的IntegerChoices model class,它是专为您的用例创建的。
We can define an UserType
model:我们可以定义一个
UserType
model:
class UserType(models.IntegerChoices):
ADMIN = 1
INSTRUCTOR = 2
STUDENT = 3
And use it in the choices
parameter of user_type
:并在
user_type
的choices
参数中使用它:
class CustomUser(AbstractUser):
user_type = models.CharField(
max_length=20, choices=UserType.choices, default=UserType.ADMIN)
And also import it in the view functions and use it for the comparisons:并将其导入视图函数并将其用于比较:
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'))
...
It also makes your code more readable, since using UserType.ADMIN
tells the reader what you want to do.它还使您的代码更具可读性,因为使用
UserType.ADMIN
会告诉读者您想要做什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.