Django管理 - 执行带有连续输出的命令

时间:2014-10-10 11:45:42

标签: python ajax django

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

以下是我的文件:

scripts.html - 脚本从此处执行,并通过AJAX调用在服务器上执行。一旦脚本执行完毕,输出将被放入div#输出。

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

只需要输出一行一行地显示。非常感谢任何帮助。

干杯, Zee的

1 个答案:

答案 0 :(得分:3)

  

“网络请求是一个可怕的地方,你想快速进出   你可以“ - 瑞克布兰森

你在这里所做的是一个架构问题。基本上,在编写CSV文件时,您将创建其他磁盘IO。 您是在网络请求中执行此操作。&#39;不是一个好主意&#39;。

然而,这也是你所描述的问题的症结所在。

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

但是:请不要这样做!

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

构建异步任务/排队系统

轮询该数据

此pycon讲座涵盖了这些技术