Django post_save信号是异步的吗?

时间:2012-08-10 09:43:11

标签: django signals

我有一个'喜欢'的功能,就像社交网络或赞成功能一样;用户点击星标/心脏/任何内容以标记所喜欢的内容。它是用ajax完成的,必须很快。这里唯一的问题是,由于某些原因,我必须为每个'喜欢'做一些任务,我发现它们是在'喜欢'视图中直接编码而且它使它变慢。我正在考虑使用信号来使这些任务的执行异步,因此视图可以立即将json发送回javascript,而无需等待任务完成。我开始为'喜欢'创建一个信号但后来发现Django的信号不是异步的,它最终会一样,视图必须等待信号完成才能发回它的响应。所以我可以尝试使该信号异步,因为它在这里和那里被解释但我也会使用post_save信号用于'like'模型,但现在我想知道视图是否可以在信号执行之前完成?

4 个答案:

答案 0 :(得分:36)

同时查看celery(或更具体地说django-celery)。它是一个异步任务调度程序/处理程序。所以你的post_save信号处理程序创建一个任务,通过芹菜获取并执行。通过这种方式,即使在不同的机器或一批机器上,您仍可以快速执行繁重的应用程序,同时执行繁重的操作。

答案 1 :(得分:22)

你想要的是一个线程。它们非常易于使用。您只需将threading.Thread子类化并编写run方法:

import threading

class LikeThread(threading.Thread):
    def __init__(self, user, liked, **kwargs):
        self.user = user
        self.liked = liked
        super(LikeThread, self).__init__(**kwargs)

    def run(self):
        # long running code here

然后,当你准备好完成任务时,你可以用以下方法解决它:

LikeThread(request.user, something).start()

您的其他视图代码或其他任何内容将恢复并返回响应,并且线程将很乐意完成其工作,直到它完成然后结束。

请参阅完整文档:http://docs.python.org/library/threading.html

答案 2 :(得分:7)

嗯,首先Django中的所有信号都不是异步的。对于您的特定情况,我认为post_save是错误的方法。最简单的方法就是触发一个ajax请求来查看你喜欢哪个动作并且不等待响应。而是在您触发请求后直接修改您的view / html。

这当然要求您事先知道您的用户可能喜欢这个项目,并且您的请求不会失败。

答案 3 :(得分:1)

async-signals包(https://github.com/nyergler/async-signals)摘要此问题。你调用异步信号函数;如果芹菜存在,包裹使用它来从工人异步发出信号;如果Celery不可用,那么包将以传统的同步方式发送信号。