76

What are the options when you want to return the user to the same page in Django and what are the pros/cons of each?

Methods I know:

  • HTTP_REFERER
  • GET parameter containing the previous URL
  • Session data to store the previous URL

Are there any other?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Al Bundy
  • 1,599
  • 1
  • 14
  • 20
  • 9
    The link says "after login". Did I asked "after login"? This question can be a real overview of this subject. It doesn't deserve -1, it deserves +1. Jeeez – Al Bundy Oct 06 '12 at 13:40
  • 2
    on the contrary the logic is no different from a get or post, it's just a redirection question there are no pro's and con's involved until you define some reasoning, your question is broad and without proper research or trial. – Hedde van der Heide Oct 06 '12 at 14:29
  • 3
    It is very different. Django login and comments redirects is built in. My question is for the other cases ;) – Al Bundy Oct 06 '12 at 15:07
  • 15
    This is absolutely NOT a duplicate of the suggested bug. The "duplicate" is a redirect after redirecting to login page, this is a redirect back to the referring page in general (think returning from a details or edit page back to a list page). Please remove the invalid duplicate flag. – Rob Osborne Jun 21 '13 at 13:28
  • +1 for removing the duplicate ban. This question is number one in google for this search term and there is only one answer, but there would be multiple (better?) ways to solve this. And it hasn't anything todo with the login situation. – tobltobs Apr 22 '16 at 12:45

4 Answers4

138

One of the way is using HTTP_REFERER header like as below:

from django.http import HttpResponseRedirect

def someview(request):
   ...
   return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

Not sure of cons of this!

Seppo Erviälä
  • 7,160
  • 7
  • 35
  • 40
Rohan
  • 52,392
  • 12
  • 90
  • 87
  • 11
    I think the big con would be the fact the many users/browsers have the http_referer turned off. – Al Bundy Oct 06 '12 at 10:16
  • 3
    Do you know how difficult it is to turn the header off? Most users don't know what it is, let alone how to turn it off. In Firefox and Chrome you have to _manually edit the preferences_ (again, not many people know how to do that); in IE you can't disable it at all (it is disabled automatically for secured sites). – Burhan Khalid Oct 06 '12 at 10:22
  • 54
    I think that it would be even better to redirect to the main page of the site if request.META is not set: return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) – nickzam Jul 31 '13 at 08:09
  • 7
    Another con is that if validation failed during submission, and the user had to correct some fileds and resubmit, then the HTTP_REFERER will be the form's url. – Asotos Apr 19 '15 at 09:47
  • 2
    See [this](https://stackoverflow.com/a/49569914/1526703) answer if you'd also like to **keep the scroll position** that it was at. – Anupam Mar 30 '18 at 07:03
23

100% working Example

For Class Based View and Function:

from django.http import HttpResponseRedirect
    ...
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

or

from django.http import HttpResponseRedirect
    ...
    return HttpResponseRedirect(self.request.META.get('HTTP_REFERER'))

Example -

class TaskNotificationReadAllView(generic.View):

    def get(self, request, *args, **kwargs):
        TaskNotification.objects.filter(assigned_to=request.user).update(read=True)   
        print(request.META.get('HTTP_REFERER'))    
        return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
Cipher
  • 2,060
  • 3
  • 30
  • 58
21

While the question and answer is old, I think it's lacking a few options. I have not find any cons with the methods, I would be happy to know if there are any?

Daniel Backman
  • 5,121
  • 1
  • 32
  • 37
4

In django view suppose you are not logged in but click on some content that content trigger some url like /board/2/new_topic then @login_required will redirect you to login page with this url

http://localhost:8000/signin/?next=/boards/2/new_topic/

so our aim is redirect to http://localhost:8000/boards/2/new_topic/ page after successful login so one line we will have to add

  if 'next' in request.GET:
        return redirect(request.GET['next'])

then if it next is there then it will redirect according to that other normal redirect .

Views.py :

def signin(request):
if request.method == "POST":
    user_login_form = UserLoginForm(request.POST)
    email = request.POST['email']
    password = request.POST['password']
    user = authenticate(request, email=email, password=password)
    if user and user.is_active:
        login(request, user)
        if 'next' in request.GET:
            return redirect(request.GET['next'])
        else:
            return redirect('home')
    else:
        return render(request, 'signin.html', context={'form': user_login_form})
else:
    user_login_form = UserLoginForm()
    return render(request, 'signin.html', context={'form': user_login_form})
Community
  • 1
  • 1
abhishek Singh
  • 332
  • 2
  • 7