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

问题描述

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

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,**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,**kwargs):
        if request.user.is_authenticated:
            return redirect ("/dashboard")
        else:
            return super(LoginView,self).get(request,**kwargs)
    
    def dispatch(self,**kwargs):
        
        if (self.request.user.is_authenticated) and (self.request.user.user_type==4):
            return redirect('/dashboard')
        else:
            return super().dispatch(request,**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,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,data['message'])
                    return redirect('/login')
        else:
            messages.add_message(self.request,'Invalid reCAPTCHA. Please try again.')
            return redirect('/login')

解决方法

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