Django:如何返回视图然后执行结束代码?

时间:2020-05-24 11:16:06

标签: python django

我想知道在Django中是否有规范的方法?

本质上是视图的构造方式,它们是返回传递给客户端的结果的函数。可以这样简单:

from django.http import HttpResponse

def my_view(request):
    return HttpResponse('This is my view!')

但让我们假设在加载my_view时,其中有些肉了:

from django.http import HttpResponse

def my_view(request):
    result = do_stuff()
    return HttpResponse(result)

do_stuff上有一些耗时的结束代码运行,即结果不依赖但运行相同的代码(也许释放资源,返回一些东西)到干净状态等。这无关紧要,原理是do_stuff包含一些要运行的代码,它有点慢,因此运行它会延迟结果的传递,但结果决不取决于

在它上面,所以它宁愿返回结果然后运行此代码。

在一个荒谬的虚构和荒谬的世界中,这可能类似于:

from django.http import HttpResponse

def my_view(request):
    result = do_stuff()
    return HttpResponse(result)
    do_more_stuff()

但是当然,由于返回的本质,do_more_stuff永远不会在现实世界中运行。

现在我可以在这里想象解决方案,将do_more_stuff()分离到后台线程或子进程中以完成操作,从而允许my_view返回。

我问的原因有两个:

  1. 我可以费力地进行测试或深入研究,这是一个小谜团,但其他人可能会对这样的过程线程的寿命有所了解。是否保证运行完成(假设运行时间适中,而不是挂起,死锁或长达一个月的运行时间等例外情况,但是这是一个普通的减少过程,但可能需要1-5秒的实时时间,在页面浏览量滞后中,从根本上注意到延迟这么长时间的视图交付)。我的意思是说view函数是在一个进程中运行的,所以关于该进程的生命周期以及它所产生的任何线程或子进程都有疑问。我可以想象如果Django在uwsgi下运行,则说不对视图进行处理是很可靠的。短暂的过程,但在那些会持续存在并继续处理视图的过程中,因此存在很长的时间,任何合理的后台线程或子过程都将能够轻松完成。

  2. 也许有一种规范的Django方式可以做到这一点。我很好奇,因为不可能是我是第一个或唯一遇到过这种需求的人(例如,发现代码的速度减慢了交付速度,但响应却不依赖于此),并且一定是开发人员遇到的非常普遍的事情,并且可能有我找不到的规范解决方案。我已经检查了中间件选项,但同样受到限制,例如,视图返回响应。

我怀疑解决方案可能存在于请求完成的信号中

https://docs.djangoproject.com/en/3.0/ref/signals/#request-finished

并且挂接到该信号的函数在传递响应后运行,并且不会延迟响应的传递。但是再次缺少测试,我不知道,因此很高兴获得输入(而我开始进行测试;-)。

1 个答案:

答案 0 :(得分:0)

尽管您无法访问请求的详细信息(发送方arg只是类,而不是请求),但信号可能会为您解决问题。

您还可以扩展响应类:Execute code in Django after response has been sent to the client

最后,如果您确实希望在单独的进程中运行事物,请考虑像芹菜(https://docs.celeryproject.org/en/stable/)这样的分布式任务队列

相关问题