Search code examples
djangodjango-viewsdjango-formsdjango-authenticationdjango-login

Django login - Preserve the 'next' parameter in the URL when the login form submission fails


I am using Django LoginView to render login form and handle the login action. Sometimes the login url has a next parameter. If the user enters wrong username and password, then it is again redirected to the login page but the url should preserve the next parameter. But I am not able to achieve it.

class CustomLoginView(LoginView):
    '''
        After successful login, django auth view should redirect the user to the next GET param

        Ref: python - Django built in login view not redirecting to next
        https://stackoverflow.com/questions/50542035/python-django-built-in-login-view-not-redirecting-to-next
    '''

    def get_success_url(self):

        next_page = self.request.POST['next']
        if next_page == '':
            next_page = '/' # if next param is not available, then redirect the user to the homepage after login.

        return next_page
    
    def form_invalid(self, form):
        response = super().form_invalid(form)
        next_url = self.request.GET.get('next') or self.request.POST.get('next')
        if next_url:
            response['Location'] = f"{self.request.path}?next={next_url}"
        return response

I was expecting the form_invalid method to preserve the next param in the url but it's not happening. I think setting response['Location'] variable in the form_invalid method is not the right way. Looking forward towards some help.


Solution

  • Сonsider using HttpResponseRedirect instead of overwriting response['Location']

    from django.shortcuts import HttpResponseRedirect
    
    class CustomLoginView(LoginView):
        ...
    
        def form_invalid(self, form):
            response = super().form_invalid(form)
            next_url = self.request.GET.get('next') or self.request.POST.get('next')
            if next_url:
                return HttpResponseRedirect(f"{self.request.path}?next={next_url}")
            return response