我有一个Django应用程序,它通过函数调用调用CLI应用程序,然后CLI应用程序执行操作并提供输出。CLI版本有一个显示进程进度的加载栏,我的计划是将其与GUI集成。这个项目很大,所以我把它简化为一个更短的项目,以便让你明白。与此演示应用程序相比,真正的应用程序具有更多细微差别和复杂性
所以,我创建了一个小的演示项目来简化你们所有人的问题。项目结构是
│ db.sqlite3
│ manage.py
│
├───testapp
│ │ admin.py
│ │ apps.py
│ │ models.py
│ │ tests.py
│ │ views.py
│ │ views.pyc
│ │ __init__.py
│ │ __init__.pyc
│ │
│ ├───cliprog
│ │ cliprogram.py
│ │ cliprogram.pyc
│ │ main.py
│ │
│ └───migrations
│ __init__.py
│
└───testproject
settings.py
settings.pyc
urls.py
urls.pyc
wsgi.py
wsgi.pyc
__init__.py
__init__.pyc
views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.conf import settings
from cliprog.main import view_helper
def index(request):
view_helper()
return HttpResponse('It works but CLI')
cliprog/main.py
from cliprogram import nice
def view_helper(): # So, that I can call this function and run my cli code
# do something
nice()
# do something
cliprog/cliprogram.py
# Print iterations progress
def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '#'):
"""
Call in a loop to create terminal progress bar
@params:
iteration - Required : current iteration (Int)
total - Required : total iterations (Int)
prefix - Optional : prefix string (Str)
suffix - Optional : suffix string (Str)
decimals - Optional : positive number of decimals in percent complete (Int)
length - Optional : character length of bar (Int)
fill - Optional : bar fill character (Str)
"""
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filledLength = int(length * iteration // total)
bar = fill * filledLength + '-' * (length - filledLength)
print '\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix)
# Print New Line on Complete
if iteration == total:
print()
#
# Sample Usage
#
from time import sleep
def nice():
# A List of Items
items = list(range(0, 57))
l = len(items)
# Initial call to print 0% progress
printProgressBar(0, l, prefix = 'Progress:', suffix = 'Complete', length = 50)
for i, item in enumerate(items):
# Do stuff...
sleep(0.1)
# Update Progress Bar
printProgressBar(i + 1, l, prefix = 'Progress:', suffix = 'Complete', length = 50)
因此,当您运行python manage.py runserver
时,其想法是视图运行CLI程序,该程序计算百分比(使用总值和当前样本数量)。但在CLI上显示它,因为它是一个CLI程序。现在,我需要的是以某种方式获得l
和i
(分别为总迭代和当前迭代)从cli文件cliprogram.py
到视图和视图将它传递到UI,在那里我将实现图形用户界面版本的加载栏。
有没有可能,当函数nice()
被触发时,它可以将值传递给views.py
,这样我就可以更新加载栏的图形用户界面版本?
注释:我已经在真正的应用程序中使用芹菜了。只是在演示应用程序中没有显示出来。所以,如果有可能,使用芹菜来解决它。答案非常受欢迎
发布于 2018-06-15 06:37:00
因为django
本质上是单线程单进程,所以我认为您需要使用multiprocessing
或threading
库来实现这一点。您的想法涉及同时运行两段代码。您可以打开一个管道在进程之间传递变量,或者如果您使用的是threading
,则可以直接读取变量。因为你给出的例子是简化的,所以我不想在这里修改你的代码,因为它涉及到对整个项目的主要修改。
我稍微修改了一下你的演示,这样它就可以作为一个独立的脚本运行,而不是django项目。但是这个想法仍然是一样的。
import multiprocessing as mp
# Print iterations progress
def printProgressBar (iteration, total, prefix = '', suffix = '', decimals = 1, length = 100, fill = '#'):
"""
Call in a loop to create terminal progress bar
@params:
iteration - Required : current iteration (Int)
total - Required : total iterations (Int)
prefix - Optional : prefix string (Str)
suffix - Optional : suffix string (Str)
decimals - Optional : positive number of decimals in percent complete (Int)
length - Optional : character length of bar (Int)
fill - Optional : bar fill character (Str)
"""
percent = ("{0:." + str(decimals) + "f}").format(100 * (iteration / float(total)))
filledLength = int(length * iteration // total)
bar = fill * filledLength + '-' * (length - filledLength)
print('\r%s |%s| %s%% %s' % (prefix, bar, percent, suffix))
# Print New Line on Complete
if iteration == total:
print()
#
# Sample Usage
#
from time import sleep
def nice(connection):
# A List of Items
items = list(range(0, 57))
l = len(items)
# Initial call to print 0% progress
printProgressBar(0, l, prefix = 'Progress:', suffix = 'Complete', length = 50)
for i, item in enumerate(items):
# Do stuff...
sleep(0.1)
# Update Progress Bar
connection.send((i,l))
printProgressBar(i + 1, l, prefix = 'Progress:', suffix = 'Complete', length = 50)
connection.close()
def view_helper(connection): # So, that I can call this function and run my cli code
# do something
nice(connection)
# do something
def index(): # your django view
conn1,conn2=mp.Pipe()
p=mp.Process(target=view_helper,args=(conn2,))
p.start()
while True:
i,l=conn1.recv()
# do things you want with your i and l
if i==l-1:
conn1.close()
p.terminate()
break
#return HttpResponse('It works but CLI')
index()
发布于 2018-06-15 07:19:41
选项1
将命令行标记添加到您的命令行界面、--no-bar
或其他工具中。启用--no-bar
后,不会显示进度条,而只打印百分比。您的GUI可以将百分比作为流读取并进行相应的更新。
注意: CLI中的其他print语句可能会搞乱这一点。
选项2
将进度条打印到stderr
,但将百分比打印到stdout
。只读图形用户界面中的stdout
。
https://stackoverflow.com/questions/50866574
复制相似问题