Azeez Aremu
Django way

Django way

Django Login Redirect

Django Login Redirect

Azeez Aremu's photo
Azeez Aremu

Published on Aug 8, 2021

3 min read

Subscribe to my newsletter and never miss my upcoming articles

I have decided to dump the Django login view and make my own, but I am now faced with the issue of

  • Redirecting the user to the homepage when login successfully seems easy 😋
  • Redirecting user to previously requested page upon being redirect to login if stumbled on the login_required decorator

Here is my login view

def Login(request):

    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            user = authenticate(request, email=form.cleaned_data.get('email'), password=form.cleaned_data.get('password'))
            if user is not None:
                if user.is_verified:
                    login(request,user)
                    #This will redirect user to the next page but if there is no next page it redirect the user to the homepage
                    #redirect logic here
                else:
                    messages.error(request, 'Please confirm your email')
                    return render(request, 'users/login.html', {'form':form})
            else:
                messages.error(request, "Invalid credentials provided")
                return redirect('login')

    return render(request, 'users/login.html')

After much trial and error, I came to notice the next hidden input field we normally attached to the login form i.e

<input type="hidden" name="next" value="{{ next }}">

And so I went back to the documentation and see that I can actually play around with this parameter to determine my redirect.

According to my design, the next only has value when the login form is only being presented by the login_reqired decorator and the value will be the previously requested path for instance if a user wanted to view a checkout view that can only be accessed by logged-in users then the user will be redirected to the login page and the new path will now be

http://127.0.0.1:8000/login/?next=/checkout/pizza/

i.e the next now has the value of /checkout/pizza/ and upon successful login, Django is expected to redirect back to the path below automatically

http://127.0.0.1:8000/checkout/pizza/

So I added the line below to update my login view after the line that actually login the user

return redirect(request.GET.get('next','/'))

The line above will redirect the user to the previously requested page if the next has parameter but will redirect to the homepage if the next parameter is empty which is what the "/" does. So my new custom login function now becomes

def Login(request):

    if request.method == 'POST':
        form = LoginForm(request.POST)
        if form.is_valid():
            user = authenticate(request, email=form.cleaned_data.get('email'), password=form.cleaned_data.get('password'))
            if user is not None:
                if user.is_verified:
                    login(request,user)
                    #This will redirect user to the next page but if there is no next page it redirect the user to the homepage
                    return redirect(request.GET.get('next','/'))
                else:
                    messages.error(request, 'Please confirm your email')
                    return render(request, 'users/login.html', {'form':form})
            else:
                messages.error(request, "Invalid credentials provided")
                return redirect('login')

    return render(request, 'users/login.html')

And not to forget, my settings.py file was updated with the line below

LOGIN_URL = '/login/'

This is to tell Django which path to take when to force a user to log in.

Hope this helps someone out there !!!.

 
Share this