我有一个问题,Django可以做多线程的工作吗?
这就是我想要做的事情:单击网页上的按钮,然后在model.py中有一些功能开始运行,例如,从互联网抓取一些数据,完成后,它会返回给用户结果。
我想我必须打开一个新线程来执行model.py中的函数,有人能告诉我怎么做吗?非常感谢你。
答案 0 :(得分:13)
以下是您所描述内容的一个示例。
User sends request
Django receives => spawns a thread to do something else.
main thread finishes && other thread finishes
... (later upon completion of both tasks)
response is sent to user as a package.
更好的方式:
User sends request
Django receives => lets Celery know "hey! do this!"
main thread finishes
response is sent to user
...(later)
user receives balance of transaction
答案 1 :(得分:2)
如this answer所示,您可以使用线程包执行异步任务。每个人似乎都推荐Celery,但是对于执行简单但长期运行的任务来说,这通常是多余的。我认为使用线程实际上更容易,更透明。
这是一个异步搜寻器的简单示例:
#views.py
import threading
from .models import Crawl
def startCrawl(request):
task = Crawl()
task.save()
t = threading.Thread(target=doCrawl,args=[task.id])
t.setDaemon(True)
t.start()
return JsonResponse({'id':task.id})
def checkCrawl(request,id):
task = Crawl.objects.get(pk=id)
return JsonResponse({'is_done':task.is_done, result:task.result})
def doCrawl(id):
task = Crawl.objects.get(pk=id)
# Do crawling, etc.
task.result = result
task.is_done = True
task.save()
您的前端可以请求startTask
开始抓取,它可以使用checkCrawl
进行Ajax请求对其进行检查,该检查将返回true并在完成时返回结果。>
答案 2 :(得分:-1)
如果您不想在项目中添加一些过度杀伤框架,只需使用subprocess.Popen:
def my_command(request):
command = '/my/command/to/run' # Can even be 'python manage.py somecommand'
subprocess.Popen(command, shell=True)
return HttpResponse(status=204)