如何在Django中重定向并附带POST数据

92 投票
9 回答
113892 浏览
提问于 2025-04-15 23:51

在处理Django的views.py文件中的POST请求时,有时候我需要把请求重定向到另一个网址。这个网址是由同一个views.py文件中的另一个函数来处理的。我想知道有没有办法做到这一点,同时还能保留原来的POST数据。

更新:我想进一步解释一下我为什么想这么做。
我有两个网页应用(我们称它们为AppA和AppB),它们都接受用户在文本框中输入的数据。当用户点击提交时,数据会被处理,并显示详细结果。AppA和AppB期待的数据类型是不同的。有时候,用户会错误地把AppB的数据提交到AppA。这种情况下,我想把他们重定向到AppB,并显示AppB的结果,或者至少让AppB填充他们在AppA中输入的数据。

另外:

  • 客户希望保持两个独立的应用,而不是把它们合并成一个。

  • 我不能展示代码,因为它属于客户。

更新2:
我决定遵循KISS原则(保持简单)。我把两个应用合并成一个,这样事情变得更简单、更稳健;我应该能说服客户这是最好的选择。感谢大家的反馈。如果我真的要维持两个应用的话,我觉得使用会话(sessions)会是个好办法,感谢Matthew J Morrison的建议。同时也感谢Dzida,他的评论让我思考了设计和简化的问题。

9 个回答

27

你需要使用一种叫做 HTTP 1.1 临时重定向 的东西 (307)。

不过,Django 的 redirect()HTTPResponseRedirect(永久重定向)只会返回 301 或 302 状态码。你需要自己来实现这个功能:

from django.http import HttpResponse, iri_to_uri
class HttpResponseTemporaryRedirect(HttpResponse):
    status_code = 307

    def __init__(self, redirect_to):
        HttpResponse.__init__(self)
        self['Location'] = iri_to_uri(redirect_to)

你还可以查看 django.http 模块

编辑:

在最近的 Django 版本中,修改 iri_to_uri 的导入方式为:

from django.utils.encoding import iri_to_uri
65

我觉得我会这样处理这个情况:把帖子的数据保存在会话中,然后在不需要的时候把它删除。这样,即使帖子已经消失,我也能在重定向后访问到原始的帖子数据。

这样做能满足你的需求吗?

这里有一个我建议的代码示例:(请注意,这段代码没有经过测试)

def some_view(request):
    #do some stuff
    request.session['_old_post'] = request.POST
    return HttpResponseRedirect('next_view')

def next_view(request):
    old_post = request.session.get('_old_post')
    #do some stuff using old_post

还有一点需要注意……如果你在做这个的同时还要上传文件,我就不建议这样做。

68

如果你遇到了这样的情况,可能需要重新考虑一下你的设计。

这是HTTP的一个限制,POST数据不能和重定向一起使用。

你能描述一下你想要实现的目标吗?也许我们可以想出一些好的解决办法。

如果你不想像Matthew建议的那样使用会话,你可以把POST参数通过GET的方式传递到新页面(不过要考虑一些限制,比如安全性和GET参数在查询字符串中的最大长度)。

更新一下你的更新:)我觉得你有两个网页应用,而这两个应用使用同一个views.py,这听起来有点奇怪(我理解得对吗?)。无论如何,考虑一下把你的POST数据通过GET传递到合适的视图(当然前提是这些数据不是敏感信息)。

撰写回答