Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
417 views
in Technique[技术] by (71.8m points)

Django redirect to login url with next ,without using method decorator

I have multiple links on my page which redirects user to take quiz. Some quiz requires user to login or create an account and some does not.

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)

I would like user to redirect like how method decorator does

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

but instead I get /login/

I would like my user to come back to the page instead of going to "/dashboard" In my settings I have

LOGIN_REDIRECT_URL ="/dashboard"

My LoginView:

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. 
'
                                        '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')
question from:https://stackoverflow.com/questions/65904520/django-redirect-to-login-url-with-next-without-using-method-decorator

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You should be fine by using @login_required() decorator docs are here. This appends a ?next=... field which within login field you can take from the request.REQUEST.get('next', '/dashboard') and use this for redirect on successful login also look up this question to see if any other answer there satisifies the requirements Also since you don't want decorators you can try saving to session as request.session["next"]=(source url) and within login view get session param and use it


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...