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

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

问题描述

我有一个脚本,我正在构建一个界面,以便人们可以在上传CSV文件后执行。我能够执行所有操作,并且脚本正常运行,但是如何显示连续输出?我应该对代码做些什么修改?

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?

以下是我的文件:

scripts.html - 脚本是从这里执行并通过AJAX调用在服务器上执行。执行脚本后,输出将被放入div#输出。

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 - AJAX在这里发送,命令通过Django管理执行

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.

干杯,
Zee

Cheers, Zee

推荐答案


网络请求是一个可怕的地方,你想尽可能快速地进出
- Rick Branson

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

你在这里做的是一个建筑问题。基本上,您在编写CSV文件时创建额外的磁盘IO。 您正在Web请求中执行此操作。不是一个好主意。

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.

快速肮脏:
您可以从django管理命令获取返回值喜欢这样。传递给jquery的ajax调用的成功方法作为您的数据。

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.

但是:请不要这样!

您需要一个异步任务系统来切换该csv文件的写入。此外,您要将数据写入您的网页可以通过(轮询,流媒体或Websockets 的某处(dbms / nosql) )这不是微不足道的事情,但最终的结果是非常值得的。以下是一些已验证的django-stack选项解决这种类型的问题。

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.

构建异步任务/排队系统

  • celery
  • Rabbit the broker used by celery
  • memcached / mongoDB / reddis

轮询该数据

  • what are longpolling and websockets
  • websockets vs long polling

这个pycon谈话涵盖了这些技术

  • Messaging at Scale at Instagram

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

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