43 votos

Cómo transmitir un HttpResponse con Django

Estoy tratando de conseguir el 'hola mundo' de streaming de trabajo sobre respuestas para Django (1.2). Me di cuenta de cómo el uso de un generador y de la yield función. Pero la respuesta aún no la transmisión. Sospecho que hay un middleware que la retirada del estiércol con ella-tal vez ETAG calculadora? Pero no estoy seguro de cómo desactivarlo. Puede alguien por favor ayuda?

Aquí está el "hola mundo" de la transmisión que tengo hasta ahora:

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)

39voto

Leopd Puntos 12652

Usted puede deshabilitar el ETAG middleware mediante la condición de decorador. Que va a obtener su respuesta al flujo a través de HTTP. Usted puede confirmar esto con una herramienta de línea de comandos como curl. Pero probablemente no será suficiente para obtener su navegador para mostrar la respuesta ya que transmite. Para fomentar el navegador para mostrar la respuesta como arroyos, usted puede pulsar un montón de espacio en blanco abajo de la tubería a la fuerza de sus búferes para llenar. Ejemplo de la siguiente manera:

from django.views.decorators.http import condition

@condition(etag_func=None)
def stream_response(request):
    resp = HttpResponse( stream_response_generator(), mimetype='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"

27voto

Marwan Alsabbagh Puntos 4245

Muchas de las django middleware le impide la transmisión de contenido. Mucho de este middleware debe ser activado si desea utilizar el django admin de la aplicación, así que esta puede ser una molestia. Por suerte, esto ha sido resuelto en el django 1.5. Usted puede utilizar el StreamingHttpResponse para indicar que desea transmitir los resultados de la espalda y todos los middleware que se incluye con django es consciente de ello y actúa en consecuencia para no búfer de su salida de contenido, pero enviarla hacia abajo de la línea. El código podría ser algo como lo siguiente para utilizar el nuevo StreamingHttpResponse objeto.

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)

Nota sobre Apache

He probado el de arriba en Apache 2.2 con Ubuntu 13.04. El módulo de apache mod_deflate que fue habilitado por defecto en la instalación que he probado va de búfer el contenido que se está tratando de transmitir hasta que se alcanza un determinado tamaño de bloque, a continuación, se gzip el contenido y enviarlo al navegador. Esto evitará que el ejemplo anterior de trabajo como desee. Una forma de evitar esto es para desactivar el mod_deflate poniendo la siguiente línea en tu configuración de apache:

SetEnvIf Request_URI ^/mysite no-gzip=1

Esto se discute más en el Cómo deshabilitar mod_deflate en apache2? pregunta.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: