Django 使用 next 重定向到登录 url,而不使用方法装饰器

时间:2021-01-26 15:46:44

标签: django django-views django-forms django-login

我的页面上有多个链接可重定向用户参加测验。 有些测验要求用户登录或创建帐户,有些则不需要。

def dispatch(self, request, *args, **kwargs):
    self.quiz = get_object_or_404(Quiz, url=self.kwargs['quiz_name'])
    
            
    if self.quiz.draft and not request.user.has_perm('quiz.change_quiz'):
        raise PermissionDenied

    try:
        self.logged_in_user = self.request.user.is_authenticated()
    except TypeError:
        self.logged_in_user = self.request.user.is_authenticated

    if self.logged_in_user:
        self.sitting = Sitting.objects.user_sitting(request.user,
                                                    self.quiz)
    else:
        self.sitting = self.anon_load_sitting()

    if self.sitting is False:            
        if self.logged_in_user:
            return render(request, self.single_complete_template_name)
        else:
            return redirect(settings.LOGIN_URL)            
    
    return super(QuizTake, self).dispatch(request, *args, **kwargs)

我希望用户像方法装饰器那样重定向

login/?next=/quiz/f506cb92-ccca-49ff-b2e5-730bbfea6a5a/take/

但我得到了 /login/

我希望我的用户回到页面而不是去“/dashboard” 在我的设置中,我有

LOGIN_REDIRECT_URL ="/dashboard"

我的登录视图:

class LoginView(FormView):
    template_name = 'login.html'
    form_class = LoginForm
    success_url = '/dashboard'

    def get(self, request, *args, **kwargs):
        if request.user.is_authenticated:
            return redirect ("/dashboard")
        else:
            return super(LoginView, self).get(request, *args, **kwargs)
    
    def dispatch(self, request, *args, **kwargs):
        
        if (self.request.user.is_authenticated) and (self.request.user.user_type==4):
            return redirect('/dashboard')
        else:
            return super().dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        """Use this to add extra context."""       
        context = super(LoginView, self).get_context_data(**kwargs)
        if 'show_captcha' in self.request.session:
            show_captcha = self.request.session['show_captcha']
            context['show_captcha'] = True
        return context
    
    def form_valid(self, form):
        user = form.login(self.request)        
        
        recaptcha_response = self.request.POST.get('g-recaptcha-response')
        url = 'https://www.google.com/recaptcha/api/siteverify'
        payload = {
            'secret': settings.GOOGLE_RECAPTCHA_SECRET_KEY,
            'response': recaptcha_response
        }
        data = urllib.parse.urlencode(payload).encode()
        req = urllib.request.Request(url, data=data)

        # verify the token submitted with the form is valid
        response = urllib.request.urlopen(req)
        result = json.loads(response.read().decode())
        if result['success']:
            if user.two_factor_auth is False and (user.phone_number_verified is True):
                login(self.request, user) 
                try:
                    UserLog.objects.filter(username=user.id).update(failed_attempt=0)
                except Exception:
                    print("No failed attempts ")
                   
                return redirect('/dashboard')
            
            else:
                try:
                    response = send_verfication_code(user)
                    pass
                except Exception as e:
                    messages.add_message(self.request, messages.ERROR,
                                        'verification code not sent. \n'
                                        'Please retry logging in.')
                    return redirect('/login')
                data = json.loads(response.text)

                if data['success'] == False:
                    messages.add_message(self.request, messages.ERROR,
                                    data['message'])
                    return redirect('/login')

                
                if data['success'] == True:
                    self.request.method = "GET"
                    print(self.request.method)
                    kwargs = {'user':user}
                    return PhoneVerificationView(self.request, **kwargs)
                else:
                    messages.add_message(self.request, messages.ERROR,
                            data['message'])
                    return redirect('/login')
        else:
            messages.add_message(self.request, messages.ERROR, 'Invalid reCAPTCHA. Please try again.')
            return redirect('/login')

1 个答案:

答案 0 :(得分:0)

使用@login_required() 装饰器文档应该没问题here。 这会附加一个 ?next=... 字段,您可以在登录字段中从 request.REQUEST.get('next', '/dashboard') 中获取该字段,并将其用于成功登录时的重定向,也可以查找此 {{3}查看是否有其他答案满足要求 此外,由于您不想要装饰器,您可以尝试将会话保存为 request.session["next"]=(source url) 并在登录视图中获取会话参数并使用它