我正在向Django视图发送一个AJAX请求,这可能会耗费大量时间。然而,它经历了一些明确定义的步骤,所以我想向用户打印状态指示器,让它知道什么时候完成了某件事并且已经移动到下一个。
如果我使用PHP,它可能看起来像这样,使用flush函数:
do_something();
print 'Done doing something!';
flush();
do_something_else();
print 'Done doing something else!';
flush();
我如何与Django一起做同样的事情?看看the documentation我看到HttpResponse对象有一个flush方法,但是它必须要说的是“这个方法使一个HttpResponse实例成为一个类似文件的对象。” - 我不确定那是我想要的。我很难理解如何在Django中完成这项任务,因为我必须返回响应并且无法控制内容何时进入浏览器。
答案 0 :(得分:9)
大多数网络服务器(例如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没有缓冲,你的前端服务器可能也是,而客户端也可能是。这就是大多数事情都使用拉动更新的原因:一个单独的界面来查询长时间运行的请求的状态。
(我希望能够为此类事情进行可靠的推送更新......)
答案 1 :(得分:3)
我不确定你需要使用flush()函数。
您的AJAX请求应该转到django视图。
如果您的步骤可以分解,请保持简单并为每个步骤创建一个视图。 这样一个进程就完成了,您可以通过AJAX更新用户并启动下一个请求。
<强> views.py 强>
def do_something(request):
# stuff here
return HttpResponse()
def do_something_else(request):
# more stuff
return HttpResponse()