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

问题描述 投票:77回答:8

[在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的意见,使我开始思考设计和简化。

django
8个回答
54
投票

如果您遇到此类问题,则极有可能需要修改设计。

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

您能描述您要完成的工作,也许我们可以考虑一些巧妙的解决方案。

如果您不希望按照Matthew的建议使用会话,则可以将GET中的POST参数传递到新页面(考虑一些限制,例如安全性和查询字符串中GET参数的最大长度)。

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


51
投票

我认为如何处理这种情况将是在会话中保存帖子数据,然后在不再需要它时将其删除。这样,即使该帖子消失了,我也可以在重定向后访问原始帖子数据。

这对您想要的工作有用吗?

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

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

要记住的另一件事...如果您正在执行此操作并且还上传了文件,则我不会这样做。


22
投票

您需要使用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

9
投票

使用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


4
投票

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

r.json()

1
投票

您可以将rendercontext与它一起使用:

requests

您可以在模板中检索vars:

requests.post

1
投票

我最近遇到了类似的问题。

[基本上,我有一个表格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很小且不是那么动态的情况下有效。


0
投票

如果处理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之后没有重定向,您是否不担心由于用户刷新页面而导致重复数据?

© www.soinside.com 2019 - 2024. All rights reserved.