如何用Djangostream式传输HttpResponse

我试图得到Django(1.2)的stream式响应的“hello world”。 我想出了如何使用发生器和yield函数。 但是响应仍然不stream。 我怀疑有一个中间件,可能是ETAG计算器? 但我不知道如何禁用它。 有人可以帮忙吗?

到目前为止,这里是stream媒体的“hello world”:

 def stream_response(request): resp = HttpResponse( stream_response_generator()) return resp def stream_response_generator(): for x in range(1,11): yield "%s\n" % x # Returns a chunk of the response to the browser time.sleep(1) 

您可以使用条件装饰器禁用ETAG中间件。 这将得到你的回应通过HTTPstream回。 你可以用curl这样的命令行工具来确认。 但是,它可能不足以让您的浏览器显示响应stream。 为了鼓励浏览器在stream式传输时显示响应,可以向pipe道中推送一堆空白,以强制缓冲区填充。 示例如下:

 from django.views.decorators.http import condition @condition(etag_func=None) def stream_response(request): resp = HttpResponse( stream_response_generator(), content_type='text/html') return resp def stream_response_generator(): yield "<html><body>\n" for x in range(1,11): yield "<div>%s</div>\n" % x yield " " * 1024 # Encourage browser to render incrementally time.sleep(1) yield "</body></html>\n" 

很多django中间件会阻止你传输内容。 如果你想使用djangopipe理应用程序,这个中间件需要被启用,所以这可能是一个烦恼。 幸运的是,这已经在django 1.5版本中解决了。 您可以使用StreamingHttpResponse来指示您想要将结果进行stream式传输,并且所有与django一起提供的中间件都知道这一点,并相应地采取行动,不缓冲您的内容输出,而是直接将其发送出去。 您的代码将如下所示使用新的StreamingHttpResponse对象。

 def stream_response(request): return StreamingHttpResponse(stream_response_generator()) def stream_response_generator(): for x in range(1,11): yield "%s\n" % x # Returns a chunk of the response to the browser time.sleep(1) 

关于Apache的注意事项

我使用Ubuntu 13.04在Apache 2.2上testing了上述内容。 默认情况下,在我testing的设置中启用的apache模块mod_deflate将缓冲您尝试stream式传输的内容,直到达到特定的块大小,然后它将gzip内容并将其发送到浏览器。 这将防止上述示例按需要工作。 避免这种情况的一种方法是通过在你的apacheconfiguration中join下面这行来禁用mod_deflate:

 SetEnvIf Request_URI ^/mysite no-gzip=1 

这将在如何禁用apache2中的mod_deflate中讨论。 题。