如何将变量从CLI程序传递到Python视图以更新Django UI?



我有一个 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 程序。 现在,我需要的是我想以某种方式从 cli 文件cliprogram.py到视图获取li(分别为总迭代和当前迭代(,视图会将其传递给 UI,我将在其中实现加载栏的 GUI 版本。

当函数nice()被三重时,是否有可能将值传递给views.py以便我可以更新加载栏的 GUI 版本?

: 我已经将芹菜用于真正的应用程序。只是没有在演示应用程序中显示它。所以,如果有什么可能的话,用芹菜来解决它。非常欢迎回答

选项 1

将命令行标志添加到您的 CLI、--no-bar或其他东西。启用--no-bar后,不显示进度条,只打印百分比。您的 GUI 可以将百分比作为流读取并相应地更新。

注意:CLI 中的其他打印语句可能会搞砸这一点。

选项 2

将进度条打印到stderr,但将百分比打印到stdout。从 GUI 中只读stdout

因为django本质上是单线程单进程,所以我认为您需要使用multiprocessingthreading库来做到这一点。您的想法涉及同时运行两段代码。您可以打开管道以在进程之间传递变量,或者如果您使用的是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()

相关内容

  • 没有找到相关文章