【发布时间】:2020-09-11 01:42:51
【问题描述】:
我想知道在 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-5 秒的实时时间和延迟这么长时间的视图交付在页面视图延迟中是非常明显的)。我的意思是视图函数是在一个进程中运行的,因此存在关于该进程的生命周期以及它产生的任何线程或子进程的问题。我有点想象如果 Django 在 uwsgi 下运行说视图没有被处理是很健壮的短暂的进程,但在那些徘徊并继续处理视图的进程中,因此长期存在,任何合理的后台线程或子进程都将能够轻松完成。
也许有一种规范的 Django 方法可以做到这一点。我很好奇,因为我不可能是第一个或唯一一个满足这种需求的人(即在一个减慢交付但不依赖于响应的视图中找到代码)并且它必须是开发人员遇到的相当普遍的事情,并且可能有一个我没有找到的规范解决方案。我检查了中间件选项,但它同样受到限制,即就像视图返回响应一样。
我怀疑解决方案可能存在于 request-finished 信号中:
https://docs.djangoproject.com/en/3.0/ref/signals/#request-finished
并且挂钩到该信号的函数在响应传递后运行并且不会延迟响应的传递。但是我不知道又没有测试它,所以很高兴输入(当我跑去测试它时;-)。
【问题讨论】:
-
你会想要使用像芹菜这样的任务队列docs.celeryproject.org/en/stable/django/…
-
如果社区投票,社区投票和三票显然关闭了这个问题,因为它是基于意见的,无法用事实回答。我只能建议向 Django 专家社区询问规范方法可以说是在任何一个阵营中(事实上可以回答,有或没有规范方法或可以用意见回答,因为没有,这就是我的d 建议做)。关于规范方法的事情是它出现在(Django 文档的)规范中。我还没有找到一个。但怀疑可能埋在某个地方。