Flo*_*ann 19 django http httpresponse django-middleware django-views
在我的Django应用程序中,我想跟踪响应是否已成功发送到客户端.我很清楚在像HTTP这样的无连接协议中没有"防水"方式来确保客户端已经接收(并显示)了响应,所以这不是关键任务功能,但我仍然希望在最新的可能时间.响应将不是HTML,因此任何来自客户端的回调(使用Javascript或IMG标签等)都是不可能的.
我能找到的"最新"钩子是在中间件列表的第一个位置添加一个实现process_response的自定义中间件,但根据我的理解,这是在构造实际响应并发送到客户端之前执行的.Django中是否有任何钩子/事件在响应成功发送后执行代码?
Flo*_*ann 21
我目前要使用的方法是使用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
Run Code Online (Sandbox Code Playgroud)
通过阅读Django代码,我非常确信HttpResponse.close()是将代码注入请求处理的最新点.我不确定与上述方法相比,这种方法是否确实存在更好的处理错误情况,所以我现在暂时搁置这个问题.
我更喜欢这种方法的原因是lazerscience的回答中提到的其他方法,它可以单独在视图中设置,不需要安装中间件.另一方面,使用request_finished信号将不允许我访问响应对象.
如果您需要大量执行此操作,一个有用的技巧是拥有一个特殊的响应类,例如:
class ResponseThen(Response):
def __init__(self, data, then_callback, **kwargs):
super().__init__(data, **kwargs)
self.then_callback = then_callback
def close(self):
super().close()
self.then_callback()
def some_view(request):
# ...code to run before response is returned to client
def do_after():
# ...code to run *after* response is returned to client
return ResponseThen(some_data, do_after, status=status.HTTP_200_OK)
Run Code Online (Sandbox Code Playgroud)
如果您想要快速/ hacky的“即发即弃”解决方案,而又无需费心集成适当的任务队列或从您的应用中分离出单独的微服务,则...将有帮助。
| 归档时间: |
|
| 查看次数: |
5984 次 |
| 最近记录: |