jörg jörg - 6 days ago 5
Python Question

Django: Redirect to previous page after login

I'm trying to build a simple website with login functionality very similar to the one here on SO.
The user should be able to browse the site as an anonymous user and there will be a login link on every page. When clicking on the login link the user will be taken to the login form. After a successful login the user should be taken back to the page from where he clicked the login link in the first place.
I'm guessing that I have to somehow pass the url of the current page to the view that handles the login form but I can't really get it to work.

EDIT:
I figured it out. I linked to the login form by passing the current page as a GET parameter and then used 'next' to redirect to that page. Thanks!

EDIT 2:
My explanation did not seem to be clear so as requested here is my code:
Lets say we are on a page foo.html and we are not logged in. Now we would like to have a link on foo.html that links to login.html. There we can login and are then redirected back to foo.html.
The link on foo.html looks like this:

<a href='/login/?next={{ request.path }}'>Login</a>


Now I wrote a custom login view that looks somewhat like this:

def login_view(request):
redirect_to = request.REQUEST.get('next', '')
if request.method=='POST':
#create login form...
if valid login credentials have been entered:
return HttpResponseRedirect(redirect_to)
#...
return render_to_response('login.html', locals())


And the important line in login.html:

<form method="post" action="./?next={{ redirect_to }}">


So yeah thats pretty much it, hope that makes it clear.

Answer

You do not need to make an extra view for this, the functionality is already built in.

First each page with a login link needs to know the current path, and the easiest way is to add the request context preprosessor to settings.py (the 4 first are default), then the request object will be available in each request:

settings.py:

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.core.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    "django.core.context_processors.request",
)

Then add in the template you want the Login link:

base.html:

<a href="{% url django.contrib.auth.views.login %}?next={{request.path}}">Login</a>

This will add a GET argument to the login page that points back to the current page.

The login template can then be as simple as this:

registration/login.html:

{% block content %}
<form method="post" action="">
  {{form.as_p}}
<input type="submit" value="Login">
</form>
{% endblock %}
Comments