在Django 2.1中使用login-required decorator

2024-04-26 11:09:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个基本要求,我有一个登录页面,当用户登录后,它会重定向到一个页面。在

如果用户没有登录,并且他打开了那个url,他将被重定向到登录页面,在成功登录之后,他被重定向到他打开的url。在

登录:http://127.0.0.1:8000/w_dashboard/login/

另一页:http://127.0.0.1:8000/w_dashboard/roaster/

我有一个名为w_dashboard的应用程序。在

现在在设置页面,我声明

Settings.py

STATIC_URL = '/static/'
LOGIN_URL = '/w_dashboard/login/'

Login.html

^{pr2}$

wüu dashboard的URL文件:

from django.urls import path
from . import views
from django.conf.urls import url

urlpatterns = [
    #url(r'^$', views.HomePageView.as_view()),
    url(r'^$', views.LoginPageView.as_view()),
    url(r'^login/$', views.LoginPageView.as_view(), name = 'login'),
    url(r'^roaster/$', views.RoasterPageView.as_view(), name="roaster"),
    url(r'^manual_login/$', views.RoasterPageView.as_view(), name="mLogin"),

]

现在,w_dashboard视图.py公司名称:

class LoginPageView(TemplateView):
    def get(self, request, *args, **kwargs):
        if request.method == 'GET':
            print("Get request")

            return render(request, 'login.html', context=None)

    def post(self, request, *args, **kwargs):
        if request.method == 'POST':
            print("POST request")
            print(request.POST['user'])
            a = models.login_validate(request.POST['user'],request.POST['password'])
            if a[0] == 0:
                print("inside if ")
                messages.error(request, 'username or password not correct')
                return render(request, 'login.html', context=None)
            elif a[0] == 1:
                print("inside elif")
                user = emp_user()
                user.name = a[1]
                print(user.last_login)
                print(user.name)
                user.save()
                login(request, user)
                return redirect(request.GET.get('next', 'roaster'))
            else:
                print("in else")
                return render(request, 'login.html', context=None)


class RoasterPageView(TemplateView):
    @login_required
    def get(self, request, *args, **kwargs):
        print(request, request.user)
        return render(request, 'roaster.html', context=None)

我在w_dashboardmodels.py中有一个自定义模型名emp_user。在

class emp_user(models.Model):
    name = models.TextField()
    last_login = models.DateTimeField(default=datetime.now)

现在的问题是,我得到了以下错误:

Internal Server Error: /w_dashboard/roaster/
Traceback (most recent call last):
  File "/Users/driftking9987/.conda/envs/w_management/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/Users/driftking9987/.conda/envs/w_management/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/driftking9987/.conda/envs/w_management/lib/python3.6/site-packages/django/core/handlers/base.py", line 124, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/driftking9987/.conda/envs/w_management/lib/python3.6/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/driftking9987/.conda/envs/w_management/lib/python3.6/site-packages/django/views/generic/base.py", line 88, in dispatch
    return handler(request, *args, **kwargs)
  File "/Users/driftking9987/.conda/envs/w_management/lib/python3.6/site-packages/django/contrib/auth/decorators.py", line 20, in _wrapped_view
    if test_func(request.user):
AttributeError: 'RoasterPageView' object has no attribute 'user'
[31/Jan/2019 09:42:42] "GET /w_dashboard/roaster/ HTTP/1.1" 500 72039

任何线索都会有帮助。我只希望登录页面重定向到烘焙页面。如果我打开了烘焙器的url,那么它应该重定向到登录,然后再重定向到烘焙器。在

我还需要登录的用户名在烘焙器,以便我可以显示它(正在保存用户,但它没有提供所需的输出)

另外,如果用户登录,它将登录多长时间?我的意思是,假设我登录并以某种方式正确地被重定向到roaster页面,那么如果我手动打开roaster页面,我不应该被重定向到登录,这种情况能持续多久?在

谢谢


Tags: djangoinpyviewurlreturnrequestlogin
2条回答

auth修饰符应该用于函数(而不是类中的方法)。对于基于类的视图,应该使用mixin,比如LoginRequiredMixin。关于示例的更多信息可以在Django官方文档中找到-https://docs.djangoproject.com/en/2.1/topics/auth/default/

编辑:您还为用户使用自定义模型-如何实现自定义用户或扩展Django auth使用的用户模型可以在这里找到:https://docs.djangoproject.com/en/2.1/topics/auth/customizing/

这个答案基本上是为那些刚刚起步的人准备的,可能不是最优化的代码,但至少它能让你开始运行。在

首先,让我们在models.py中创建一个自定义模型。在

class AuthUser(AbstractBaseUser):
    password = models.CharField(max_length=128)
    last_login = models.DateTimeField(blank=True, null=True)
    is_superuser = models.IntegerField()
    username = models.CharField(unique=True, max_length=150)
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=150)
    email = models.CharField(null=False, unique=True, max_length=254)
    is_staff = models.IntegerField()
    is_active = models.IntegerField()
    date_joined = models.DateTimeField()

    USERNAME_FIELD = 'email'

    class Meta:
        managed = False
        db_table = 'auth_user'

setting.py中声明它。在

^{pr2}$

在我的例子中,我必须从mysql表中查询用户名/密码。所以我必须做出相应的改变。在

首先,在settings.py中添加数据库详细信息。在

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'w_s',
        'USER': 'r09ot',
        'PASSWORD': 'qw5',
        'HOST': '119.00.00.000',
        'PORT': '3306',
    }
}

现在这将在数据库中创建几个表,我们将使用auth_user创建的auth_user表来存储用户名和密码。在

现在,让我们创建自定义后端。创建一个名为auth_backends.py的文件。在

添加以下代码:

from django.contrib.auth import get_user_model, backends
from .models import AuthUser


class MySQLAuthBackend:

    def authenticate(self, request, email=None, password=None):
        print("inside auth func")
        usermodel = get_user_model()
        try:
            user = usermodel.objects.get(email=email)
            if not user:
                print("No such user")

            else:
                print("abc")
                if user.password == password:
                    print("password match")
                    return user
            # if user.check_password(password):
            #     return user

        except usermodel.DoesNotExist:
            print("inside except")
            return None

    def get_user(self, pk):
        usermodel = get_user_model()
        try:
            usermodel = get_user_model()
            return usermodel.objects.get(pk=pk)
        except usermodel.DoesNotExist:
            pass

        return None

上面的代码将查询用户名为“email”、密码为“password”的数据库。并返回用户。在

现在让我们来看看登录函数。在

def post(self, request, *args, **kwargs):
    if request.method == 'POST':
        print("POST request")
        print(request.POST['user'])
        user = authenticate(request, email=request.POST['user'], password=request.POST['password'])
        if user is not None:
            print("login success")
            user.save()
            print(user.__dict__)
            login(request, user)
            request.session.set_expiry(20)
            return redirect(request.GET.get('next', 'mLogin'))
        else:
            print("login unsuccess")
            messages.error(request, 'username or password not correct')
            return render(request, 'login.html', context=None)

这是最重要的部分。由于我们从自定义后端身份验证方法对用户进行了身份验证,user的填充方式是login方法可以接受的。简而言之,它让您登录到login函数。在

现在是login_required的一部分。既然是视图,我们将使用method_decorator,如下所示:

@method_decorator(login_required, name='dispatch')
class ManualLoginPageView(TemplateView):
    def get(self, request, *args, **kwargs):
        print("inside manual login")
        print(request.user.__dict__)
        print(request.user.get_short_name())
        return render(request, 'manualLogin.html', context=None)

同样在url.py中,添加login_required类似

url(r'^roaster/$', login_required(views.RoasterPageView.as_view()), name="roaster"),

这是在按预期工作和执行功能。在

相关问题 更多 >