Django - 刷新响应?
我正在向一个Django视图发送一个AJAX请求,这个请求可能会花费很多时间。虽然它有一些明确的步骤,但我想给用户显示一些状态指示,让他们知道什么时候完成了某个操作,什么时候又开始了下一个。
如果我使用的是PHP,可能会像这样,使用flush函数:
do_something();
print 'Done doing something!';
flush();
do_something_else();
print 'Done doing something else!';
flush();
那么在Django中我该怎么做呢?查看文档,我看到HttpResponse对象有一个flush方法,但它只说“这个方法让HttpResponse实例像一个文件对象。” - 我不确定这是否是我想要的。我很难理解在Django中该怎么做,因为我必须返回响应,并且实际上无法控制内容何时发送到浏览器。
2 个回答
我不太确定你是否需要使用flush()这个函数。
你的AJAX请求应该直接发送到一个Django的视图(view)里。
如果你的步骤可以拆分开来,尽量简单点,每个步骤都创建一个视图。这样当一个过程完成后,你就可以更新用户的信息,然后通过AJAX开始下一个请求。
views.py
def do_something(request):
# stuff here
return HttpResponse()
def do_something_else(request):
# more stuff
return HttpResponse()
大多数网络服务器(比如FCGI/SCGI)会自己处理数据的缓存,HTTP客户端也会自己处理。这种情况下,想要把数据及时发送出去并让客户端收到其实是很困难的,因为这并不是一个常见的操作。
你想做的事情,最接近的办法是把一个迭代器传给HttpResponse,然后在生成器里处理数据;大概是这样的:
def index(request):
def do_work():
step_1()
yield "step 1 complete"
step_2()
yield "step 2 complete"
step_3()
yield "step 3 complete"
return HttpResponse(do_work())
... 但这并不一定能保证数据会被及时发送出去。(这段代码没有经过测试,但你能理解这个意思;可以参考http://docs.djangoproject.com/en/dev/ref/request-response/#passing-iterators。)
大部分的基础设施其实并不期待会有分段的响应。即使Django没有进行缓存,你的前端服务器可能也在缓存,而客户端大概率也是如此。这就是为什么大多数情况下会使用拉取更新的方式:通过一个单独的接口来查询长时间运行请求的状态。
(我也希望能做到这种事情的可靠推送更新……)