How to pass HttpResponse using Django

I am trying to get a "hello world" of streaming answers running on Django (1.2). I figured out how to use the generator and yield function. But the answer is still not broadcast. I suspect there is middleware that is associated with it - maybe an ETAG calculator? But I'm not sure how to disable it. Can anybody help?

Here is the "hello world" of the streaming that I still have:

 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) 
+49
python django streaming
May 27 '10 at 16:21
source share
2 answers

You can disable ETAG middleware using a condition decorator . This will give you a response to the stream over HTTP. You can confirm this with a command line tool like curl . But probably this will not be enough to make your browser show the response as it flows. To encourage the browser to display the response as it flows, you can press a bunch of spaces down the channel to make its buffers fill up. Example:

 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" 
+43
May 27 '10 at 16:48
source

A lot of django middleware will prevent streaming content. Most of this middleware should be included if you want to use the django admin application, so this can be annoying. Fortunately, this was allowed in the release of django 1.5 . You can use StreamingHttpResponse to indicate that you want to pass the results back, and all the middleware that comes with django is aware of this and acts accordingly not to buffer the output of your content, but to send it directly along the line. Then your code will look like this to use the new StreamingHttpResponse object.

 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 Note

I tested above on Apache 2.2 with Ubuntu 13.04. The apache module mod_deflate, which was enabled by default in the test setup, will buffer the content you are trying to transfer until it reaches a certain block size, then it will gzip the content and send it to the browser. This will prevent the above example from working as desired. One way to avoid this is to disable mod_deflate by putting the following line in the apache configuration:

 SetEnvIf Request_URI ^/mysite no-gzip=1 

This is discussed in How to disable mod_deflate in apache2? question.

+34
Nov 17 '12 at 10:33
source



All Articles