Django:如何重定向帖子并传递帖子数据

Fun*_*der 73 django

在Django views.py文件中处理POST请求时,我有时需要将其重定向到另一个URL.我重定向到的这个url是由同一个Django views.py文件中的另一个函数处理的.有没有办法做到这一点并维护原始的POST数据?

更新:更多解释为什么我想这样做.我有两个网络应用程序(我们称之为AppA和AppB),它接受用户输入文本字段的数据.当用户单击"提交"时,将处理数据并显示详细结果.AppA和AppB期望不同类型的数据.有时,用户错误地将AppB类型数据发布到AppA.当发生这种情况时,我想将它们重定向到AppB并显示AppB结果,或者至少将它们填入他们输入AppA的数据中.

也:

  • 客户需要两个独立的应用程序,而不是将它们合并为一个.

  • 我无法显示代码,因为它属于客户端.

更新2:我已经确定KISS是这里最好的原则.我将这两个应用程序合并为一个,使事情更简单,更健壮; 我应该能够说服客户,这也是最好的方式.感谢所有的好评.如果我要按照描述维护两个应用程序,那么我认为会话就是这样做的方式 - 感谢Matthew J Morrison的建议.感谢Dzida,他的评论让我想到了设计和简化.

dzi*_*ida 53

如果您遇到这样的问题,您可能需要修改设计.

这是HTTP的限制,POST数据不能与重定向一起使用.

你能描述一下你想要完成什么,也许我们可以考虑一些简洁的解决方案.

如果您不想像Matthew建议的那样使用会话,您可以将GET中的POST参数传递给新页面(考虑一些限制,例如查询字符串中的安全性和GET参数的最大长度).

更新到你的更新:)我觉得你有2个网络应用程序,这些应用程序使用一个views.py(我是对的吗?)听起来很奇怪.无论如何,考虑将您的数据从GET中的POST传递到正确的视图(当然数据不敏感).

  • 我可以看到他试图做的事情可能是有效的,如果他试图处理过期的登录,这将迫使用户在提交表格后登录...在这种情况下,他将要保留已提交的数据,并且在完成登录屏幕后不强制用户重新输入所有内容. (2认同)

Mat*_*son 48

我想我可能会处理这种情况的方法是在会话中保存帖子数据,然后在我不再需要它时将其删除.这样,即使该帖子消失,我也可以在重定向后访问原始帖子数据.

这会对你想做的事情有用吗?

这是我建议的代码示例:(请记住这是未经测试的代码)

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
Run Code Online (Sandbox Code Playgroud)

还有一件事需要记住......如果你这样做并且还要上传文件,我不会这样做.

  • 那么,这取决于您存储会话的位置.最近我一直看到人们使用带有memcached的整个服务器进行会话并在每个请求中进行负载平衡(使用循环法).我不想给你建议我不能支持,但我会将文件保存为临时文件,并在会话中只获取它的链接.似乎这些天没有人用完公羊. (4认同)

Llo*_*eki 22

您需要使用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)
Run Code Online (Sandbox Code Playgroud)

另请参见django.http模块.

编辑:

在最近的Django版本上,将iri_to_uri导入更改为:

from django.utils.encoding import iri_to_uri
Run Code Online (Sandbox Code Playgroud)


Ane*_*R S 8

使用requestspackage.Its非常容易实现

pip install requests
Run Code Online (Sandbox Code Playgroud)

然后你可以用任何方法调用任何网址并传输数据

在您的视图中导入请求

import requests
Run Code Online (Sandbox Code Playgroud)

发布数据,请遵循格式

r = requests.post('http://yourdomain/path/', data = {'key':'value'})
Run Code Online (Sandbox Code Playgroud)

要在django视图中获取绝对URL,请使用

request.build_absolute_uri(reverse('view_name'))

因此django视图代码看起来像

r = requests.post(
            request.build_absolute_uri(reverse('view_name')), 
            data = {'key':'value'}
    )
Run Code Online (Sandbox Code Playgroud)

其中r是与所述响应对象status_codecontent属性. r.status_code给出状态代码(成功时它将是200)并r.content给出响应体.有一个json方法(r.json())将响应转换为json格式

要求

requests.post

  • 我相信这不会改变用户浏览器中的 URL。听起来OP想要转发到一个新的URL (2认同)

Kom*_*omu 6

只需使用相同的请求对象从旧视图调用新视图即可。当然,它不会导致重定向,但如果您关心的只是将数据从一个视图“传输”到另一个视图,那么它应该可以工作。
我测试了以下代码片段并且它有效。

from django.views.generic import View

class MyOldView(View):
    def post(self, request):
        return MyNewView().post(request)

class MyNewView(View):
    def post(self, request):
        my_data = request.body
        print "look Ma; my data made it over here:", my_data
Run Code Online (Sandbox Code Playgroud)