我有一个'喜欢'的功能,就像社交网络或赞成功能一样;用户点击星标/心脏/任何内容以标记所喜欢的内容。它是用ajax完成的,必须很快。这里唯一的问题是,由于某些原因,我必须为每个'喜欢'做一些任务,我发现它们是在'喜欢'视图中直接编码而且它使它变慢。我正在考虑使用信号来使这些任务的执行异步,因此视图可以立即将json发送回javascript,而无需等待任务完成。我开始为'喜欢'创建一个信号但后来发现Django的信号不是异步的,它最终会一样,视图必须等待信号完成才能发回它的响应。所以我可以尝试使该信号异步,因为它在这里和那里被解释但我也会使用post_save信号用于'like'模型,但现在我想知道视图是否可以在信号执行之前完成?
答案 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()
您的其他视图代码或其他任何内容将恢复并返回响应,并且线程将很乐意完成其工作,直到它完成然后结束。
答案 2 :(得分:7)
嗯,首先Django中的所有信号都不是异步的。对于您的特定情况,我认为post_save
是错误的方法。最简单的方法就是触发一个ajax请求来查看你喜欢哪个动作并且不等待响应。而是在您触发请求后直接修改您的view / html。
这当然要求您事先知道您的用户可能喜欢这个项目,并且您的请求不会失败。
答案 3 :(得分:1)
async-signals
包(https://github.com/nyergler/async-signals)摘要此问题。你调用异步信号函数;如果芹菜存在,包裹使用它来从工人异步发出信号;如果Celery不可用,那么包将以传统的同步方式发送信号。