响应发送到客户端后,在Django中执行代码

时间:2022-02-28 15:37:28

In my Django application I want to keep track of whether a response has been sent to the client successfully. I am well aware that there is no "watertight" way in a connectionless protocol like HTTP to ensure the client has received (and displayed) a response, so this will not be mission-critical functionality, but still I want to do this at the latest possible time. The response will not be HTML so any callbacks from the client (using Javascript or IMG tags etc.) are not possible.

在我的Django应用程序中,我想跟踪响应是否已成功发送到客户端。我很清楚在HTTP之类的无连接协议中没有“防水”的方式来确保客户端已经接收(并显示)了响应,因此这不是关键任务功能,但我仍然希望在最新的可能时间。响应将不是HTML,因此无法从客户端(使用Javascript或IMG标签等)进行任何回调。

The "latest" hook I can find would be adding a custom middleware implementing process_response at the first position of the middleware list, but to my understanding this is executed before the actual response is constructed and sent to the client. Are there any hooks/events in Django to execute code after the response has been sent successfully?

我能找到的“最新”钩子是在中间件列表的第一个位置添加一个实现process_response的自定义中间件,但据我了解,这是在构建实际响应并发送给客户端之前执行的。 Django中是否有任何钩子/事件在成功发送响应后执行代码?

2 个解决方案

#1


14  

The method I am going for at the moment uses a subclass of HttpResponse:

我目前要使用的方法是使用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

By reading the Django code I am very much convinced that HttpResponse.close() is the latest point to inject code into the request handling. I am not sure if there really are error cases that are handled better by this method compared to the ones mentioned above, so I am leaving the question open for now.

通过阅读Django代码,我非常确信HttpResponse.close()是将代码注入请求处理的最新点。我不确定与上面提到的方法相比,这种方法是否确实存在更好的处理错误情况,所以我现在暂时搁置这个问题。

The reasons I prefer this approach to the others mentioned in lazerscience's answer are that it can be set up in the view alone and does not require middleware to be installed. Using the request_finished signal, on the other hand, wouldn't allow me to access the response object.

我更喜欢这种方法的原因是lazerscience的回答中提到的其他方法,它可以单独在视图中设置,不需要安装中间件。另一方面,使用request_finished信号将不允许我访问响应对象。

#2


1  

I suppose when talking about middleware you are thinking about the middleware's process_request method, but there's also a process_response method that is called when the HttpResponse object is returned. I guess that will be the latest moment where you can find a hook that you can use.

我想在讨论中间件时你正在考虑中间件的process_request方法,但是当返回HttpResponse对象时,还会调用process_response方法。我想这将是你可以找到一个可以使用的钩子的最新时刻。

Furthermore there's also a request_finished signal being fired.

此外,还有一个request_finished信号被触发。

#1


14  

The method I am going for at the moment uses a subclass of HttpResponse:

我目前要使用的方法是使用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

By reading the Django code I am very much convinced that HttpResponse.close() is the latest point to inject code into the request handling. I am not sure if there really are error cases that are handled better by this method compared to the ones mentioned above, so I am leaving the question open for now.

通过阅读Django代码,我非常确信HttpResponse.close()是将代码注入请求处理的最新点。我不确定与上面提到的方法相比,这种方法是否确实存在更好的处理错误情况,所以我现在暂时搁置这个问题。

The reasons I prefer this approach to the others mentioned in lazerscience's answer are that it can be set up in the view alone and does not require middleware to be installed. Using the request_finished signal, on the other hand, wouldn't allow me to access the response object.

我更喜欢这种方法的原因是lazerscience的回答中提到的其他方法,它可以单独在视图中设置,不需要安装中间件。另一方面,使用request_finished信号将不允许我访问响应对象。

#2


1  

I suppose when talking about middleware you are thinking about the middleware's process_request method, but there's also a process_response method that is called when the HttpResponse object is returned. I guess that will be the latest moment where you can find a hook that you can use.

我想在讨论中间件时你正在考虑中间件的process_request方法,但是当返回HttpResponse对象时,还会调用process_response方法。我想这将是你可以找到一个可以使用的钩子的最新时刻。

Furthermore there's also a request_finished signal being fired.

此外,还有一个request_finished信号被触发。