Django:如何redirectpost并传递发布数据
在Django views.py文件中处理POST请求时,有时需要将其redirect到另一个url。 这个我redirect到的URL由同一个Django的views.py文件中的另一个函数处理。 有没有办法做到这一点,维护原始的POST数据?
更新:更多的解释,为什么我想这样做。 我有两个networking应用程序(让我们称之为AppA和AppB)接受用户input到文本字段中的数据。 当用户点击提交时,数据被处理并显示详细的结果。 AppA和AppB期待不同types的数据。 有时用户错误地将AppBtypes数据发布到AppA。 发生这种情况时,我想将它们redirect到AppB,并显示AppB结果,或者至less将它们input到AppA中。
也:
-
客户端需要两个单独的应用程序,而不是将它们合并成一个。
-
我无法显示代码,因为它属于客户端。
更新2:我已经决定KISS是这里最好的原则。 我已经将这两个应用程序合并为一个使事情变得更简单和更强大的应用程序。 我应该能够说服客户,这也是最好的办法。 感谢所有伟大的反馈。 如果我要保持两个应用程序的描述,那么我认为会议将是这样做 – 感谢马修J莫里森提出这一点。 感谢Dzida,因为他的评论让我思考了devise和简化。
如果你遇到这样的问题,你可能需要修改你的devise。
这是POST数据无法与redirect一起使用的HTTP限制。
你能描述一下你想要完成什么,也许那么我们可以考虑一些简洁的解决scheme。
如果你不想使用会话,马修build议你可以在GET中传递POST参数到新页面(考虑一些限制,如查询string中的GET参数的安全性和最大长度)。
更新到你的更新:)这听起来很奇怪,你有2个Web应用程序,这些应用程序使用一个views.py(我是吗?)。 无论如何,考虑将GET中的数据从GET传递到正确的视图(当然数据不敏感)。
我想我可能会处理这种情况将是保存会议中的发布数据,然后删除它,当我不再需要它。 这样我可以访问redirect后的原始发布数据,即使该post已经消失。
这将工作,你想要做什么?
以下是我所build议的代码示例:(请记住这是未经testing的代码)
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
还有一件事要记住…如果你这样做,也上传文件,我不会这样做。
您需要使用HTTP 1.1临时redirect(307)。 不幸的是,Django的redirect()和HTTPResponse(永久)redirect只返回一个301或302.(请参阅django.http模块 )
你必须自己实现它:
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)
使用requests
包。它很容易实现
pip install requests
那么你可以用任何方法调用任何url和传输数据
在你的意见导入请求
import requests
发布数据,请按照格式
r = requests.post('http://yourdomain/path/', data = {'key':'value'})
在django视图中获取绝对url,使用
request.build_absolute_uri(reverse('view_name'))
因此,Django查看代码看起来像
r = requests.post( request.build_absolute_uri(reverse('view_name')), data = {'key':'value'} )
其中r
是具有status_code
和content
属性的响应对象。 r.status_code
给出了状态码(成功的时候是200), r.content
给出了响应的主体。 有一个json方法( r.json()
),将响应转换为json格式
要求
requests.post
如果在将POST处理到AppB
之后使用redirect,则实际上可以通过AppB
方法调用AppA
方法。
一个例子:
def is_appa_request(request): ## do some magic. return False or True is_appb_request = is_appa_request def AppA(request): if is_appb_request(request): return AppB(request) ## Process AppA. return HttpResponseRedirect('/appa/thank_you/') def AppB(request): if is_appa_request(request): return AppA(request) ## Process AppB. return HttpResponseRedirect('/appb/thank_you/')
这应该为最终用户提供一个透明的体验,而雇用你的客户可能永远不会知道这个差别。
如果您在POST后没有redirect,您是否担心由于用户刷新页面而导致重复的数据?
只需使用相同的请求对象从旧视图中调用新视图即可。 当然,这样做不会导致redirect,但是如果你关心的只是将数据从一个视图“转移”到另一个视图,那么它应该起作用。
我testing了下面的代码片段,它的工作原理。
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
你可以使用渲染和上下文 :
Render(request,"your template path", {'vad name' : var value}
您可以在模板中收回增值税:
{% If var name %} {{ var name }} {% endif %}