首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将变量从CLI程序传递到Python视图以更新Django UI?

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

Stack Overflow用户
提问于 2018-06-15 06:05:16
回答 2查看 80关注 0票数 1

我有一个Django应用程序,它通过函数调用调用CLI应用程序,然后CLI应用程序执行操作并提供输出。CLI版本有一个显示进程进度的加载栏,我的计划是将其与GUI集成。这个项目很大,所以我把它简化为一个更短的项目,以便让你明白。与此演示应用程序相比,真正的应用程序具有更多细微差别和复杂性

所以,我创建了一个小的演示项目来简化你们所有人的问题。项目结构是

代码语言:javascript
复制
│   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

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
# 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程序。现在,我需要的是以某种方式获得li (分别为总迭代和当前迭代)从cli文件cliprogram.py到视图和视图将它传递到UI,在那里我将实现图形用户界面版本的加载栏。

有没有可能,当函数nice()被触发时,它可以将值传递给views.py,这样我就可以更新加载栏的图形用户界面版本?

注释:我已经在真正的应用程序中使用芹菜了。只是在演示应用程序中没有显示出来。所以,如果有可能,使用芹菜来解决它。答案非常受欢迎

EN

回答 2

Stack Overflow用户

发布于 2018-06-15 06:37:00

因为django本质上是单线程单进程,所以我认为您需要使用multiprocessingthreading库来实现这一点。您的想法涉及同时运行两段代码。您可以打开一个管道在进程之间传递变量,或者如果您使用的是threading,则可以直接读取变量。因为你给出的例子是简化的,所以我不想在这里修改你的代码,因为它涉及到对整个项目的主要修改。

我稍微修改了一下你的演示,这样它就可以作为一个独立的脚本运行,而不是django项目。但是这个想法仍然是一样的。

代码语言:javascript
复制
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()
票数 0
EN

Stack Overflow用户

发布于 2018-06-15 07:19:41

选项1

将命令行标记添加到您的命令行界面、--no-bar或其他工具中。启用--no-bar后,不会显示进度条,而只打印百分比。您的GUI可以将百分比作为流读取并进行相应的更新。

注意: CLI中的其他print语句可能会搞乱这一点。

选项2

将进度条打印到stderr,但将百分比打印到stdout。只读图形用户界面中的stdout

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50866574

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档