我有一个脚本,我正在构建一个界面,以便人们可以在上传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的
答案 0 :(得分:3)
“网络请求是一个可怕的地方,你想快速进出 你可以“ - 瑞克布兰森
你在这里所做的是一个架构问题。基本上,在编写CSV文件时,您将创建其他磁盘IO。 您是在网络请求中执行此操作。&#39;不是一个好主意&#39;。
然而,这也是你所描述的问题的症结所在。
快点肮脏: 您可以从django管理命令like so获取返回值。将其传递给jquery的ajax调用的成功方法作为您的数据。
但是:请不要这样做!
您需要一个异步任务系统来切换该csv文件的写入。此外,您希望通过(polling, streaming or websockets)将您的网页可以侦听的某些地方(dbms / nosql)写入数据。这不是一项微不足道的工作,但最终结果非常值得付出努力。以下是解决此类问题的proven django-stack choices。
构建异步任务/排队系统
轮询该数据
此pycon讲座涵盖了这些技术。