[在Django views.py文件中处理POST请求时,有时需要将其重定向到另一个URL。我重定向到的网址是由同一Django views.py文件中的另一个函数处理的。有办法做到这一点并维护原始POST数据吗?
更新:我为什么要这样做的更多解释。我有两个Web应用程序(我们称它们为AppA和AppB),它们接受用户输入到文本字段中的数据。当用户单击提交时,将处理数据并显示详细结果。 AppA和AppB需要不同类型的数据。有时用户错误地将AppB类型数据发布到AppA。发生这种情况时,我想将它们重定向到AppB并显示AppB结果,或者至少用他们输入AppA的数据填充它。
也:
客户端需要两个单独的应用程序,而不是将它们组合成一个。
我无法显示该代码,因为它属于客户端。
更新2:我已经决定,KISS是最好的原则。我将这两个应用程序组合在一起,使事情变得更简单,更强大。我应该能够说服客户,这也是最好的方法。感谢您的宝贵意见。如果我要按所述维护两个应用程序,那么我想通过会议来做到这一点-感谢Matthew J Morrison提出的建议。感谢Dzida的意见,使我开始思考设计和简化。
如果您遇到此类问题,则极有可能需要修改设计。
这是HTTP的限制,POST数据不能与重定向一起使用。
您能描述您要完成的工作,也许我们可以考虑一些巧妙的解决方案。
如果您不希望按照Matthew的建议使用会话,则可以将GET中的POST参数传递到新页面(考虑一些限制,例如安全性和查询字符串中GET参数的最大长度)。
更新您的更新:)您有2个Web应用程序,而这些应用程序使用一个views.py(对吗?),这对我来说听起来很奇怪。无论如何,请考虑将数据从GET中的POST传递到正确的视图(以防万一数据当然不敏感)。
我认为如何处理这种情况将是在会话中保存帖子数据,然后在不再需要它时将其删除。这样,即使该帖子消失了,我也可以在重定向后访问原始帖子数据。
这对您想要的工作有用吗?
这里是我建议的代码示例:(请记住,这是未经测试的代码)
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 Temporary Redirect(307)。
[很遗憾,Django redirect()
和redirect()
(永久)仅返回301或302。您必须自己实现它:
HTTPResponseRedirect
另请参见HTTPResponseRedirect
。
编辑:
在最新的Django版本上,将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 module
使用iri_to_uri
包。很容易实现
iri_to_uri
然后您可以使用任何方法调用任何URL并传输数据
您认为导入请求
from django.utils.encoding import iri_to_uri
发布数据,遵循格式
requests
要在Django视图中获取绝对URL,请使用
pip install requests
因此,django视图代码看起来像
import requests
其中r = requests.post('http://yourdomain/path/', data = {'key':'value'})
是具有request.build_absolute_uri(reverse('view_name'))
和r = requests.post(
request.build_absolute_uri(reverse('view_name')),
data = {'key':'value'}
)
属性的响应对象。r
给出状态码(成功时将为200),status_code
给出响应主体。有一个json方法(content
)会将响应转换为json格式
r.status_code
r.content
只需使用相同的请求对象从旧视图中调用新视图。当然,它不会导致这样的重定向,但是,如果您只关心将数据从一个视图“传输”到另一个视图,则它应该可以工作。我测试了以下代码段,它可以正常工作。
r.json()
我最近遇到了类似的问题。
[基本上,我有一个表格A,提交后会显示另一个表格B,其中包含一些结果+一个表格。提交B后,我想向用户显示一些警报,并使用户仅停留在B上。
我解决此问题的方法是,在B的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}
而且我对A-> B和B-> B使用了相同的视图。现在,我只需要区分请求是来自A还是来自B并相应地呈现。
{% If var name %}
{{ var name }}
{% endif %}
但是这仅在表单B很小且不是那么动态的情况下有效。
如果处理POST至<output>
后仍在使用重定向,则实际上可以通过从<output name="xyz" value="xyz">{{xyz}}</output>
方法中调用def view1(request):
if "xyz" in request.POST:
# request from B
# do some processing
return render(request, 'page.html', {"xyz":request.POST["xyz"]})
else:
# request from A
res = foo() # some random function
return render(request, 'page.html', {"xyz":res})
方法来摆脱困境。
示例:
AppB
这应该为最终用户带来透明的体验,雇用您的客户可能永远不会知道区别。
如果您在POST之后没有重定向,您是否不担心由于用户刷新页面而导致重复数据?