Django: Redirect to previous page after login

Question:

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.

Asked By: jörg

||

Answers:

Django’s built-in authentication works the way you want.

Their login pages include a next query string which is the page to return to after login.

Look at http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.login_required

Answered By: S.Lott

See django docs for views.login(), you supply a ‘next’ value (as a hidden field) on the input form to redirect to after a successful login.

Answered By: YHVH

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!

Answered By: jörg

This may not be a “best practice”, but I’ve successfully used this before:

return HttpResponseRedirect(request.META.get('HTTP_REFERER','/'))
Answered By: Grant

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 %}
Answered By: sverrejoh

I encountered the same problem. This solution allows me to keep using the generic login view:

urlpatterns += patterns('django.views.generic.simple',
    (r'^accounts/profile/$', 'redirect_to', {'url': 'generic_account_url'}),
)
Answered By: moo

In registration/login.html (nested within templates folder) if you insert the following line, the page will render like Django’s original admin login page:

{% include "admin/login.html" %}

Note: The file should contain above lines only.

Answered By: Harshith J.V.

To support full urls with param/values you’d need:

?next={{ request.get_full_path|urlencode }}

instead of just:

?next={{ request.path }}
Answered By: arntg

You can also do this

<input type="hidden" name="text" value="{% url 'dashboard' %}" />
Answered By: JREAM
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.