我是Web开发的新手。我想上传一个文件并在 Celery 任务中处理它,并使用 AJAX 显示进度百分比。我使用了一些这样的示例,这是我的代码:
views.py:
def importnewdata(request):
if request.method == 'POST':
form = RawFileAddressForm(request.POST, request.FILES)
if form.is_valid():
file = request.FILES['file']
file_name = default_storage.save("sample.txt", file)
task = process_file.delay(file_name)
return HttpResponse(json.dumps({'task_id': task.id}), content_type='application/json')
else:
return HttpResponse("Error1!")
else:
form = RawFileAddressForm()
return render(request, 'modelmanager/importnewdata.html', {'form': form})
def get_task_info(request):
task_id = request.GET.get('task_id', None)
if task_id is not None:
task = AsyncResult(task_id)
data = {
'state': task.state,
'result': task.result,
}
return HttpResponse(json.dumps(data), content_type='application/json')
else:
return HttpResponse('No job id given.')
forms.py:
class RawFileAddressForm(forms.Form):
file = forms.FileField()
导入新数据.html:
<!DOCTYPE html>
<html>
<head>
<title>import new raw data to db</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body style="text-align: center;">
<h1>select your file to process it!</h1>
<progress id="progress-bar" value="0" max="100" style="display:none; margin-bottom: 1em;"></progress>
<form id="process-raw-data" action="/modelmanager/importnewdata/" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit"/>
</form>
<script type="text/javascript">
var frm = $('#process-raw-data');
var pgrbar = $('#progress-bar');
frm.submit(function () {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
if (data.task_id != null) {
get_task_info(data.task_id);
}
},
error: function (data) {
frm.html("error!");
}
});
return false;
});
function get_task_info(task_id) {
$.ajax({
type: 'get',
url: '/modelmanager/get-task-info/',
data: {'task_id': task_id},
success: function (data) {
frm.html('');
if (data.state == 'PENDING') {
frm.html('Please wait...');
}
else if (data.state == 'PROGRESS') {
pgrbar.css('display', 'inline');
pgrbar.val(data.result.percent);
frm.html('lines processed ' + data.result.current + ' out of ' + data.result.total);
}
else if(data.state == 'SUCCESS'){
pgrbar.css('display', 'none');
frm.html('Successfully Completed!');
}
if (data.state != 'SUCCESS') {
setTimeout(function () {
get_task_info(task_id)
}, 500);
}
},
error: function (data) {
frm.html("error!");
}
});
}
</script>
</body>
</html>
问题是单击提交按钮后没有任何反应。我得到了:
"POST/modelmanager/importnewdata/HTTP/1.1" 200 10
在《Wireshark》中,我看到了
错误1!
作为回应。这意味着表单无效,但是当我从 html 文件中删除 JS 部分时,它会返回一个成功创建的芹菜任务 ID 的 json 对象。这意味着形式是有效的。 任何帮助。谢谢。
谢谢大家。你帮了我很多!:)
最后这是我的解决方案:
views.py:
def importnewdata(request):
cntx = {}
if request.method == 'POST':
form = RawFileAddressForm(request.POST, request.FILES)
if form.is_valid():
file = request.FILES['file']
file_name = default_storage.save("sample.txt", file)
task = process_file.delay(file_name)
cntx['task_id'] = task.id
return render(request, 'modelmanager/importnewdata.html', cntx)
else:
return render(request, 'modelmanager/importnewdata.html', {'form':form})
else:
form = RawFileAddressForm()
return render(request, 'modelmanager/importnewdata.html', {'form': form})
def get_task_info(request):
task_id = request.GET.get('task_id', None)
if task_id is not None:
task = AsyncResult(task_id)
data = {
'state': task.state,
'result': task.result,
}
return HttpResponse(json.dumps(data), content_type='application/json')
else:
return HttpResponse('No job id given.')
导入新数据.html:
<!DOCTYPE html>
<html>
<head>
<title>import new raw data to db</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body style="text-align: center;">
<h1>select your file to process it!</h1>
<progress id="progress-bar" value="0" max="100" style="display:none; margin-bottom: 1em;"></progress>
<form id="process-raw-data" action="/modelmanager/importnewdata/" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
{% if task_id %}
<script type="text/javascript">
var taskid = "{{task_id}}";
var frm = $('#process-raw-data');
var pgrbar = $('#progress-bar');
get_task_info(taskid);
function get_task_info(tid) {
$.ajax({
type: 'get',
url: '/modelmanager/get-task-info/',
data: {'task_id': tid},
success: function (data) {
frm.html('');
if (data.state == 'PENDING') {
frm.html('Please wait...');
}
else if (data.state == 'PROGRESS') {
pgrbar.css('display', 'inline');
pgrbar.val(data.result.percent);
frm.html('lines processed ' + data.result.current + ' out of ' + data.result.total);
}
else if(data.state == 'SUCCESS'){
pgrbar.css('display', 'none');
frm.html('Successfully Completed!');
}
if (data.state != 'SUCCESS') {
setTimeout(function () {
get_task_info(tid)
}, 500);
}
},
error: function (data) {
frm.html("error!");
}
});
}
</script>
{% endif %}
</body>
</html>