Django可以做多线程的工作吗?

时间:2013-07-11 19:24:08

标签: django multithreading

我有一个问题,Django可以做多线程的工作吗?

这就是我想要做的事情:单击网页上的按钮,然后在model.py中有一些功能开始运行,例如,从互联网抓取一些数据,完成后,它会返回给用户结果。

我想我必须打开一个新线程来执行model.py中的函数,有人能告诉我怎么做吗?非常感谢你。

3 个答案:

答案 0 :(得分:13)

  1. 是的,它可以是多线程的,但通常一个人使用Celery来做同等的事情。 You can read about how in the celery-django tutorial.
  2. 实际上很少想强迫用户等待网站。虽然这比超时的风险更好。
  3. 以下是您所描述内容的一个示例。

    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)