Episode 25 of 32

Redirecting After Login

Use the next parameter to redirect users to the page they originally requested after logging in — improving the user experience.

Redirecting After Login

When @login_required redirects to login, it adds ?next=/original/page/ to the URL. Let us use this next parameter to send users back to where they came from after logging in.

How ?next Works

User visits /articles/create/ (not logged in)
    ↓
@login_required redirects to:
/accounts/login/?next=/articles/create/
    ↓
User logs in
    ↓
Redirect to /articles/create/ (not the default page)

Updated Login View

# accounts/views.py
def login_view(request):
    if request.method == 'POST':
        form = AuthenticationForm(data=request.POST)
        if form.is_valid():
            user = form.get_user()
            login(request, user)
            # Check for ?next parameter
            if 'next' in request.POST:
                return redirect(request.POST.get('next'))
            else:
                return redirect('articles:list')
    else:
        form = AuthenticationForm()
    return render(request, 'accounts/login.html', {
        'form': form
    })

Passing next to the Form

<!-- templates/accounts/login.html -->
{% extends 'base_layout.html' %}

{% block content %}
    <h2>Log In</h2>
    <form method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <!-- Pass the next value as a hidden field -->
        <input type="hidden" name="next" value="{{ request.GET.next }}">
        <button type="submit">Log In</button>
    </form>
{% endblock %}

The hidden input captures the next value from the URL query string and includes it in the POST data when the form is submitted.

Key Takeaways

  • @login_required adds ?next= to the login redirect URL
  • Pass next as a hidden form field so it is included in the POST data
  • After login, check for next and redirect there if it exists
  • Fall back to a default page if next is not present