Django的管理 - 使用连续输出执行命令 [英] Django management - execute command with continuous output

查看:173
本文介绍了Django的管理 - 使用连续输出执行命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我建立一个接口,使人们可以上传CSV文件后,执行脚本。我能执行的一切,都在脚本运行正常,但我怎么显示连续输出?我应该让我的code什么样的变化?

下面是我的文件:

scripts.html - 脚本都是从这里执行,并通过Ajax调用服务器上执行。输出置于DIV#输出一旦脚本执行完毕。

 < D​​IV CLASS =table_container>
    <形式方法=邮报是enctype =的multipart / form-data的数据AJAX =假> {%csrf_token%}
        < H4> Rebilling< / H4>
        < D​​IV CLASS =清除>< / DIV>
        < IMG类=加载-GIF的SRC ={{STATIC_URL}} IMG /加载-clear.gifALT =/>
        <表>
            < TBODY>
            &其中; TR>
                < TD风格=宽度:180px;><标签>上传CSV< /标签>< / TD>
                < TD>
                    <输入类型=隐藏名称=script_type值=renew_subscriptions>
                    <输入类型=文件名称=csv_file/>
                < / TD>
            < / TR>
            &其中; TR>
                < TD风格=宽度:180px;>< / TD>
                < TD>
                    <输入类型=提交名称=执行/>
                < / TD>
            < / TR>
            < / TBODY>
        < /表>
    < /形式GT;
< / DIV>

< H2>脚本输出< / H>
< D​​IV ID =输出>
    {%autoescape关闭%}

    {%endautoescape%}
< / DIV>

<脚本类型=文/ JavaScript的>
    //变量来存储你的文件
    var中的文件;

    //添加事件
    $('输入[type = file]')上('变',prepareUpload)。

    //抓斗的文件,并将其设定为我们的变量
    函数prepareUpload(事件)
    {
      文件= event.target.files;
    }

    $('表')上('提交',submitForm)。

    //抓住表单提交和上传文件
    功能submitForm(事件)
    {
        event.stopPropagation(); //停止的事情发生
        。事件preventDefault(); //完全停止的事情发生
        $(#输出)HTML()。

        变种形式= $(本);
        form.find(加载-GIF。)的CSS(显示,块)。
        form.find(输入[类型=提交])丙(禁用,真正的)。

        //创建一个FORMDATA对象,并添加文件
        VAR数据=新FORMDATA(form.get(0));

        $阿贾克斯({
            网址:'/ CRM /脚本,
            键入:POST,
            数据:数据,
            缓存:假的,
            数据类型:HTML,
            过程数据:假的,
            的contentType:假的,
            成功:函数(数据)
            {
                // console.dir(数据);
                $(#输出)HTML(数据);
            },
            错误:函数(jqXHR,textStatus,errorThrown)
            {
                这里//处理错误
                的console.log('错误:'+ textStatus);
            },
            完成:函数()
            {
                form.find(加载-GIF。)的CSS(显示,无)。
                form.find(输入[类型=提交])丙(禁用,假)。
            }
        });


        返回false;
    }
< / SCRIPT>
 

views.py - 阿贾克斯在这里发送和执行命令,通过Django的管理

 高清all_scripts(要求):#帐户页面
    #C = {}
    script_type =无
    csv_file =无
    OUT = StringIO的()

    如果request.is_ajax和request.method =='POST':
        csv_file = request.FILES.get('csv_file)

        如果csv_file:
            #打印在这里
            ###写csv_file到一个临时文件
            TUP = tempfile.mkstemp()#使tmp文件
            F = os.fdopen(TUP [0],W)#打开用于写入的tmp文件
            f.write(csv_file.read())#编写的tmp文件
            f.close()

            ###返回的文件的路径
            文件路径= TUP [1]#获得的文件路径
            #打印文件路径

            如果request.POSTscript_type:
                script_type = request.POST ['script_type']
                如果script_type ==change_credit:
                    credit_amount =无

                    如果request.POSTcredit_amount:
                        credit_amount = request.POST ['credit_amount']

                    如果request.POST功能:
                        功能= request.POST ['功能']

                        如果功能==删除:
                            management.call_command(script_type,文件路径,credit_amount,删除= [真],标准输出= OUT)
                        其他:
                            management.call_command(script_type,文件路径,credit_amount,标准输出= OUT)

                ELIF script_type ==renew_subscriptions:
                    management.call_command(script_type,文件路径,冗长= 1,互动=假,标准输出= OUT)

                打印out.getvalue()
                返回的Htt presponse(out.getvalue())

    返回render_to_response('CRM / scripts.html',context_instance = RequestContext的(要求))
 

刚需的输出线不断线来显示。任何帮助是非常AP preciated。

干杯, ZEE

解决方案
  

web请求是一个可怕的地方,你想进入和退出一样快   你可以 - 里克·布兰森

你在这里做的是创建一个架构问题。基本上你是写你的CSV文件时,创建额外的磁盘IO。 您这样做是在Web请求。不是一个好主意。

您所描述的问题但是它也是症结所在。

快速ñ肮脏的: 你可以从一个Django的管理命令返回值,像这样。传递回jQuery的Ajax调用作为数据的成功方法。

不过:<​​STRONG>请不要到

您需要的异步任务系统,随手关闭的csv文件的写入。另外,你要的地方写入数据(DBMS / NoSQL的),你的网页可以监听通过(轮询,流媒体或WebSockets的 )这不是一个简单的任务,但最终的结果是非常值得的。这里有一些证明Django的堆栈选择来解决此类问题。

建立一个异步任务处理/排队叫号系统

轮询数据

这PYCON讲座涵盖了这些技术

I have a script that I'm building an interface for so people can execute after uploading a CSV file. I'm able to execute everything and have the script run properly, but how do I display a continuous output? What changes should I make to my code?

Below are my files:

scripts.html - Scripts are executed from here and executed on the server via an AJAX call. Output is placed into div#output once the script is done executing.

<div class="table_container">
    <form method="post" enctype="multipart/form-data" data-ajax="false">{% csrf_token %}
        <h4>Rebilling</h4>
        <div class="clear"></div>
        <img class="loading-gif" src="{{ STATIC_URL }}img/loading-clear.gif" alt="" />
        <table>
            <tbody>
            <tr>
                <td style="width: 180px;"><label>Upload the CSV</label></td>
                <td>
                    <input type="hidden" name="script_type" value="renew_subscriptions">
                    <input type="file" name="csv_file" />
                </td>
            </tr>
            <tr>
                <td style="width: 180px;"></td>
                <td>
                    <input type="submit" name="Execute" />
                </td>
            </tr>
            </tbody>
        </table>
    </form> 
</div>

<h2>Script Output</h2>
<div id="output">
    {% autoescape off %}

    {% endautoescape %}
</div>

<script type="text/javascript">
    // Variable to store your files
    var files;

    // Add events
    $('input[type=file]').on('change', prepareUpload);

    // Grab the files and set them to our variable
    function prepareUpload(event)
    {
      files = event.target.files;
    }

    $('form').on('submit', submitForm);

    // Catch the form submit and upload the files
    function submitForm(event)
    {
        event.stopPropagation(); // Stop stuff happening
        event.preventDefault(); // Totally stop stuff happening
        $("#output").html("");

        var form = $(this);
        form.find(".loading-gif").css("display", "block");
        form.find("input[type='submit']").prop('disabled', true);

        // Create a formdata object and add the files
        var data = new FormData(form.get(0));

        $.ajax({
            url: '/crm/scripts',
            type: 'POST',
            data: data,
            cache: false,
            dataType: 'html',
            processData: false,
            contentType: false,
            success: function(data)
            {
                // console.dir(data);
                $("#output").html(data);
            },
            error: function(jqXHR, textStatus, errorThrown)
            {
                // Handle errors here
                console.log('ERRORS: ' + textStatus);
            },
            complete: function()
            {
                form.find(".loading-gif").css("display", "none");
                form.find("input[type='submit']").prop('disabled', false);
            }
        });


        return false;
    }
</script>

views.py - The AJAX is sent here and the command is executed through Django Management

def all_scripts(request):    # Accounts page
    # c = {}
    script_type = None
    csv_file = None
    out = StringIO()

    if request.is_ajax and request.method == 'POST':
        csv_file = request.FILES.get('csv_file')

        if csv_file:
            # print "over here"
            ### write the csv_file to a temp file
            tup = tempfile.mkstemp() # make a tmp file
            f = os.fdopen(tup[0], 'w') # open the tmp file for writing
            f.write(csv_file.read()) # write the tmp file
            f.close()

            ### return the path of the file
            filepath = tup[1] # get the filepath
            # print filepath

            if 'script_type' in request.POST:
                script_type = request.POST['script_type']
                if script_type == "change_credit":
                    credit_amount = None

                    if 'credit_amount' in request.POST:
                        credit_amount = request.POST['credit_amount']

                    if 'function' in request.POST:
                        function = request.POST['function']

                        if function == "remove":
                            management.call_command(script_type, filepath, credit_amount, remove=[True], stdout=out)
                        else:
                            management.call_command(script_type, filepath, credit_amount, stdout=out)

                elif script_type == "renew_subscriptions":
                    management.call_command(script_type, filepath, verbosity=1, interactive=False, stdout=out)

                print out.getvalue()
                return HttpResponse(out.getvalue())

    return render_to_response('crm/scripts.html', context_instance=RequestContext(request))

Just need the output to display continuously line by line. Any help is much appreciated.

Cheers, Zee

解决方案

"The web request is a scary place, you want to get in and out as quick as you can" - Rick Branson

What you have done here is created an architectural issue. Basically you are creating additional disk IO when writing your CSV file. You are doing this in the web request. 'Not a good idea'.

However its also the crux of the issue you are describing.

Quick n dirty: you could get a return value from a django management command like so. Pass that back to the success method of jquery's ajax call as your data.

However: please don't to that!

You need an async task system to hand off the write of that csv file. Additionally you want to write the data somewhere ( dbms / nosql ) that your webpage can listen for via ( polling, streaming or websockets ) This is not a trivial undertaking but the end result is well worth the effort. Here are some proven django-stack choices to solve this type of issue.

Building a Asynchronous Tasking/Queuing System

Polling for that data

This pycon talk covers these technologies.

这篇关于Django的管理 - 使用连续输出执行命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆