简体   繁体   English

django 中的中间件不断重定向,无法访问管理站点

[英]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_typechoices参数中使用它:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM