从django视图返回HttpResponse后触发函数

时间:2012-02-29 08:39:56

标签: python django decorator django-signals django-middleware

我正在开发一个django网络服务器,另一台机器(具有已知IP)可以将电子表格上传到我的网络服务器。 电子表格更新后,我想在电子表格上触发一些处理/验证/分析(可能需要> 5分钟---太长时间,其他服务器无法合理地等待回复)然后发送另一台机器(使用已知的IP)一个HttpResponse,表明数据处理已经完成。

我意识到在返回processing.data()后你无法HttpResponse,但在功能上我希望代码看起来像这样:

# processing.py
def spreadsheet(*args, **kwargs):
    print "[robot voice] processing spreadsheet........."
    views.finished_processing_spreadsheet()

# views.py
def upload_spreadsheet(request):
    print "save the spreadsheet somewhere"
    return HttpResponse("started processing spreadsheet")
    processing.data()

def finished_processing_spreadsheet():
    print "send good news to other server (with known IP)"

我知道如何单独编写每个函数,但在 processing.data()返回响应后如何有效地调用views.upload_spreadsheet

我尝试使用django's request_finished signaling framework,但在返回processing.spreadsheet()后,这不会触发HttpResponse方法。我尝试在views.upload_spreadsheet上使用装饰器同样的问题。

我清楚地知道这可能与写middleware或可能custom class-based view有关,我也没有任何经验,所以我想我会向宇宙提出这个问题。寻求一些帮助。

感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

事实上Django有一个同步模型。如果要进行真正的异步处理,则需要一个消息队列。 django最常用的是芹菜,看起来有点“矫枉过正”,但这是一个很好的答案。

为什么我们需要这个?因为在wsgi应用程序中,apache将请求提供给可执行文件,并且可执行文件返回文本。只有当可执行文件完成执行时,apache只知道请求的结束。

答案 1 :(得分:3)

您的实施问题是,如果正在处理的电子表格数量等于工作人员数量:您的网站将不再响应。

您应该使用后台任务队列,基本上有 2个进程:您的服务器和后台任务管理器。服务器应将电子表格的处理委托给后台任务管理器。后台任务完成后,它应以某种方式通知服务器。例如,它可以做model_with_spreadsheet.processed = datetime.datetime.now()。

您应该使用后台职位经理,例如django-ztask(非常简单的设置),celery(非常强大,可能在你的情况下有点过分)甚至{{3} }(显然需要部署uwsgi)。