2010-11-30 12 views
13

En mi aplicación Django deseo hacer un seguimiento de si se ha enviado una respuesta satisfactoriamente al cliente. Soy consciente de que no hay una forma "estanca" en un protocolo sin conexión como HTTP para garantizar que el cliente haya recibido (y mostrado) una respuesta, por lo que esta no será una funcionalidad de misión crítica, pero aún así quiero hacer esto en el último tiempo posible. La respuesta no será HTML, por lo que no es posible ninguna devolución de llamada del cliente (usando etiquetas Javascript o IMG, etc.).Ejecutar el código en Django después de enviar la respuesta al cliente

El "último" gancho que puedo encontrar sería agregar un middleware personalizado que implementa process_response en la primera posición de la lista de middleware, pero a mi entender esto se ejecuta antes de que se construya la respuesta real y se envíe al cliente. ¿Hay ganchos/eventos en Django para ejecutar el código después de que la respuesta se haya enviado con éxito?

Respuesta

14

El método que voy a por el momento utiliza una subclase de HttpResponse:

from django.template import loader 
from django.http import HttpResponse 

# use custom response class to override HttpResponse.close() 
class LogSuccessResponse(HttpResponse): 

    def close(self): 
     super(LogSuccessResponse, self).close() 
     # do whatever you want, this is the last codepoint in request handling 
     if self.status_code == 200: 
      print('HttpResponse successful: %s' % self.status_code) 

# this would be the view definition 
def logging_view(request): 
    response = LogSuccessResponse('Hello World', mimetype='text/plain') 
    return response 

Al leer el código de Django Estoy muy convencido de que HttpResponse.close() es el último punto para inyectar código en el manejo de la solicitud. No estoy seguro de si realmente hay casos de error que se manejan mejor con este método en comparación con los mencionados anteriormente, por lo que estoy dejando la pregunta abierta por el momento.

Las razones por las que prefiero este enfoque para las otras mencionadas en la respuesta de lazerscience son que se puede configurar solo en la vista y no requiere que se instale el middleware. Usar la señal request_finished, por otro lado, no me permitiría acceder al objeto de respuesta.

+0

¿Qué hay de malo en enviar una bandera json más simple? ¿Por qué todo lo anterior? –

+0

Tampoco entiendo lo que quiere decir con "json flag" ni puedo ver de ninguna manera JSON ayudándome con mi problema ... por favor, elabore. –

+6

Funciona bien para manejar una respuesta exitosa, pero close() no se ejecuta si el usuario interrumpe la conexión (al cerrar la pestaña o presionar el botón "detener").Defina un método \ __ del \ __ si necesita hacer algo después de que se haya manejado la respuesta, incluso si la conexión se ha interrumpido con fuerza. – vincent

1

Supongo que al hablar de middleware está pensando en el método de middleware process_request, pero también hay un process_response method que se llama cuando se devuelve el objeto HttpResponse. Supongo que será el último momento en el que puedes encontrar un gancho que puedes usar.

Además, también hay un request_finished signal que se está disparando.

+0

Conocí process_response, pero como se espera que este método devuelva una respuesta, creo que la respuesta no pudo haber sido enviada en este punto. request_finished se ve prometedor, estoy investigando eso ahora. –

+0

Comprobé request_finished y desafortunadamente se ejecuta incluso si hay una excepción cuando se maneja la solicitud. Entonces esto tampoco sirve para mis propósitos, porque solo quiero rastrear las respuestas exitosas. –

+1

Supongo que no encontrarás un momento posterior a process_response, porque eso se llama después de que HttpRequest esté completo y luego se maneja en el servidor web ... –

Cuestiones relacionadas