在Django视图

问题描述:

我张望了一下看着执行使用subprocess.Popen()的Python脚本,但我似乎无法来解决这个问题,我有。我想在我的django应用程序的视图内执行一个python脚本。我已经将要执行的代码放入django管理命令中,以便通过命令行python manage.py command-name访问它。然后我尝试使用subprocess.Popen("python manage.py command-name",shell=True)来运行此命令。在Django视图

但是,该命令可能需要一些时间来执行,所以我想认为继续并允许脚本在后台执行。使用subprocess.Popen单独似乎使视图挂起,直到剧本已经完成,所以我尝试使用一个线程(以下another SA问题):

class SubprocessThread(threading.Thread): 
def __init__(self, c): 
    self.command = c 
    self.stdout = None 
    self.stderr = None 
    threading.Thread.__init__(self) 

def run(self): 
    p = subprocess.Popen(self.command, 
         shell=True, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE) 

    self.stdout, self.stderr = p.communicate() 

,然后执行它:

t = SubprocessThread("python manage.py command-name") 
t.setDaemon(True) 
t.start() 
t.join() 

但是,视图仍然挂起:光标有一个忙符号,页面上的AJAX不加载。否则,在线程调用看起来正常完成(在脚本完成之前)之后,页面的html似乎在视图中正常加载和命令。有人可以帮帮我吗?我希望脚本能够执行并自己做,而不必在页面上保留视图或AJAX调用。

+0

我经常使用类似的模式(以'subprocess',因为'thread'被杀害视图功能退出时),并且我经常忘记在返回的东西查看功能,使浏览器挂起。然后,我责怪subporcess,而我只是忘了返回一个'HttpResponse'。检查一下! – Dunatotatos 2017-10-31 08:23:44

也许你应该使用celery

芹菜分布式消息传递基础 任务队列/作业队列。据 专注于实时操作

我浪费了很多时间试图实现类似的东西,但有同样的问题你。最终,我放弃并实施了一个豆茎队列来处理这项工作。

http://kr.github.com/beanstalkd/

我把在Django的视图中的队列中的ID,然后有一个管理命令运行消费者(通过supervisord观看)。

使用队列意味着你可以扩展到多个消费者,并允许更好地管理负载(如果有必要暂停消费者又不失所需的工作)。