在Django中启动后台任务的简单方法

56

我有一个Django网站,其中一个页面有一个按钮(或链接),当点击时会启动一个比较长的任务。显然,我希望将此任务作为后台任务启动,并立即向用户返回结果。我想使用一种简单的方法来实现这一点,而不需要像Celery这样安装和学习整个新的消息架构。我不想使用Celery!我只想使用一个简单的方法,在接下来的半个小时左右设置并运行。难道在Django中没有一种简单的方法可以做到这一点,而不必添加(又一个)第三方包吗?


你可以让服务器返回一个“请求已接收”类型的响应。如果轮询或Websockets不可用,则只需让服务器更新每个10%或25%的完成百分比值。并且为用户提供指定区域来检查任何正在运行的进程,并显示完成百分比。这样,浏览器只会在用户转到或刷新正在运行的进程页面时才与服务器进行通信。然后,如果一个进程完成了100%,就提供一个结果链接。这只是一些想法。 - Ryan G
注意:更新完成百分比值的服务器仅在服务器上[例如DB值]。如果用户转到给定页面,则可以查询此内容。此外,这将取决于您的基础架构如何处理并发连接。运行过程可能会阻塞,因此您可能需要查看类似tornado的内容。 - Ryan G
4
我非常怀疑你自己写的任何内容都不会比安装Celery更简单,安装完毕后问题就解决了。 - Daniel Roseman
3
我很怀疑你自己写的任何内容都不会比安装Celery更简单。但是,我可以想到很多比Celery更简单的工具。Celery是一款强大的软件,可以处理大规模、高容量的分布式任务,但它需要单独安装键值存储、代理等组件。如果你只想运行后台任务,那么我建议你寻找其他工具。 - Andy Baker
3个回答

67

只需使用一个线程。

import threading

t = threading.Thread(target=long_process,
                            args=args,
                            kwargs=kwargs)
t.setDaemon(True)
t.start()
return HttpResponse()

查看此问题以获取更多详细信息: Django能够执行多线程任务吗?


9
我认为这需要更多关注。最近我在使用Celery和RabbitMQ构建项目时,实际上应该使用线程。我在这里创建了一个最简示例:https://github.com/nbwoodward/django-async-threading - nbwoodward
它的效果很好,只是为了确认一下...它有没有任何缺点? - itsmehemant7

18

你可以查看一下 django-background-tasks - 它恰好能够满足你的需求,且不需要像 RabbitMQ 或 Redis 等额外的服务运行。它在数据库中管理任务队列,并具有 Django 管理命令,可以运行一次或作为定期作业。


4
虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分,并提供该链接作为参考。仅包含链接的答案如果链接页面发生更改,可能会变得无效。-【来自审查】 - Rao
3
链接指向一个解决问题的模块,而不是解决问题的描述。我不知道该如何重写这篇文章,也许你有一些建议? - user226114
3
此模块目前仅适用于Django 1.4到1.8版本。 - aboutaaron
3
今天我们将更稳定和健壮的版本(1.1.6)的 django-background-tasks 推送到了 Python 包索引。这个版本也支持最新的 Django 版本。发布说明:https://github.com/arteria/django-background-tasks/releases/tag/v1.1.6 - phi
1
有人知道如何在视图中立即启动一个后台作业(但不等待其完成),使用django-background-tasks吗? - konstunn
显示剩余5条评论

8

3
这个问题已经几年了,但是我现在一直在使用RQ来完成许多这样的任务。它非常简单易用,而且效果很好。强烈推荐使用。 - Marc
1
不确定这个“被接受的答案”如何回答问题“在Django中没有必要添加(另一个)第三方包,难道没有简单的方法吗?”,但这个项目看起来确实很不错。 - Benjamin Toueg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接