2014-10-10 22 views
1

我有一個腳本,我正在構建一個接口,以便人們可以在上傳CSV文件後執行。我能夠執行所有操作並讓腳本正常運行,但是如何顯示連續輸出?我應該對我的代碼做些什麼改變?Django管理 - 執行連續輸出命令

下面是我的文件:

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 - 阿賈克斯在這裏發送,並且指令通過Django的管理執行

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的

+0

那麼究竟什麼是你的問題?你向我們展示的代碼有什麼問題?它不起作用嗎?它會產生意外的行爲嗎? – CoryKramer 2014-10-10 11:47:24

+0

對不起,只是編輯帖子,包括一個問題。我的問題基本上是,我要改變什麼才能讓連續的輸出顯示出來? – zee 2014-10-10 12:06:17

+0

@Cyber​​能否澄清? – zee 2014-10-10 12:33:05

回答

3

「web請求是一個可怕的地方,你想進入和離開一樣快 ,你可以」 - 裏克·布蘭森

你做了什麼這裏創建了一個架構問題。基本上你在編寫你的CSV文件時創建了額外的磁盤IO。 您正在網絡請求中執行此操作。'不是個好主意'。

但它也是你所描述的問題的關鍵。

快速ñ髒: 你可以得到一個Django管理命令like so返回值。把它回傳給jquery的ajax調用的成功方法作爲你的數據。

但是:請不要那樣!

您需要一個異步任務系統才能將該csv文件寫入。此外,您想要將數據寫入某處(dbms/nosql),以便您的網頁可以通過(polling, streaming or websockets)進行監聽。這不是一件小事,但最終的結果非常值得您付出努力。這裏有一些proven django-stack choices來解決這類問題。

構建異步任務處理/排隊系統

輪詢數據

這PYCON演講包括這些技術