【问题标题】:Django management - execute command with continuous outputDjango 管理 - 执行命令并持续输出
【发布时间】:2014-10-10 11:45:42
【问题描述】:

我有一个脚本,我正在为其构建一个界面,以便人们可以在上传 CSV 文件后执行。我能够执行所有内容并让脚本正常运行,但是如何显示连续输出?我应该对我的代码进行哪些更改?

以下是我的文件:

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

<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 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))

只需要输出逐行连续显示。非常感谢任何帮助。

干杯, 泽

【问题讨论】:

  • 那么您的问题到底是什么?您向我们展示的代码有什么问题?它不工作吗?它会产生意想不到的行为吗?
  • 抱歉,刚刚编辑了帖子以包含一个问题。我的问题本质上是,我要改变什么,才能有连续的输出来显示?
  • @Cyber​​ 说明了吗?

标签: python ajax django


【解决方案1】:

“网络请求是一个可怕的地方,你想尽快进出 尽你所能”——里克·布兰森

您在这里所做的是创建了一个架构问题。基本上,您在编写 CSV 文件时会创建额外的磁盘 IO。 您正在网络请求中执行此操作。“不是一个好主意”。

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

又快又脏: 您可以从 django 管理命令like so 获得返回值。将其作为您的数据传递回 jquery 的 ajax 调用的成功方法。

但是:请不要那样做!

您需要一个异步任务系统来移交该 csv 文件的写入。此外,您希望将数据写入某处(dbms / nosql),以便您的网页可以通过(polling, streaming or websockets)侦听这不是一项微不足道的任务,但最终结果非常值得付出努力。这里有一些proven django-stack choices来解决这类问题。

构建异步任务/排队系统

轮询该数据

本次 pycon 演讲涵盖了这些技术

【讨论】:

    猜你喜欢
    • 2011-12-11
    • 2015-09-06
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多