在Django中如何重定向/返回到同一(先前的)页面?

76

在Django中,当您想要将用户返回到同一页面时,有哪些选项可用?它们各自的优缺点是什么?

我知道的方法有:

  • HTTP_REFERER
  • 包含先前URL的GET参数
  • 使用会话数据存储先前的URL

还有其他方法吗?


9
这个链接说“登录后”。我问过“登录后”了吗? 这个问题可能是这个主题的真正概述。它不应该得到-1分,而应该得到+1分。天哪 - Al Bundy
2
相反,逻辑与“获取”或“提交”并无不同,这只是一个重定向问题,没有任何利弊相关,直到你提出一些理由,你的问题才会具有广泛性和缺乏适当的研究或试验。 - Hedde van der Heide
3
非常不同。Django登录和评论重定向已经内置。我的问题是针对其他情况的;) - Al Bundy
15
这绝对不是所提出的错误建议的重复。 "重复" 是在重定向到登录页面后重定向,而这是通常情况下返回到引用页面的重定向(例如从详细信息或编辑页面返回到列表页面)。请删除无效的重复标记。 - Rob Osborne
+1 移除重复禁令。这个问题在谷歌搜索中排名第一,只有一个答案,但可能有多种(更好的?)解决方法。而且它与登录情况无关。 - tobltobs
4个回答

139

其中一种方法是使用类似下面的 HTTP_REFERER 头:

from django.http import HttpResponseRedirect

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

不确定这样做的缺点是什么!


11
大问题在于许多用户/浏览器已关闭了http_referer。 - Al Bundy
3
你知道关闭标题有多难吗?大多数用户不知道它是什么,更不用说如何关闭它了。在Firefox和Chrome中,你必须手动编辑偏好设置(而且很少有人知道如何这样做);在IE中,你根本无法禁用它(对于安全网站,它会自动禁用)。 - Burhan Khalid
54
如果 request.META 没有设置,我认为将重定向到网站的主页会更好:return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))。 - nickzam
7
另一个缺点是,如果提交时验证失败,并且用户必须更正一些字段并重新提交,那么HTTP_REFERER将是表单的网址。 - Asotos
2
如果您还想保留滚动位置,请参阅这个答案。 - Anupam

23

100%工作示例

对于基于类的视图和函数:

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

例子 -

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'))

21

虽然这个问题和答案是老的,但我认为它缺少一些选项。我没有发现任何使用这种方法的缺点,如果有的话,我很乐意知道。


1
你提供的三个例子都是指请求URL(例如/login/),而不是当前页面的URL(例如/)。 - Adrien Lemaire
链接的文档解释了这些方法的作用,并且它们按照 Django 文档中描述的方式工作。 - Daniel Backman

4
在Django视图中,假设您未登录,但单击某些内容会触发像/board/2/new_topic这样的URL,然后@login_required将重定向到带有此URL的登录页面。
http://localhost:8000/signin/?next=/boards/2/new_topic/
因此,我们的目标是在成功登录后重定向到http://localhost:8000/boards/2/new_topic/页面,所以我们需要添加一行代码。
  if 'next' in request.GET:
        return redirect(request.GET['next'])

如果下一个是存在的,则会根据另一个普通重定向进行重定向。

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})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接