>我有一个页面(foo.com/process
),您可以在其中生成数据报告。有时需要生成的数据量很大,因此需要一段时间。因此,我做了一个芹菜任务来处理PDF生成方面的事情。单击PDF图像时会生成报告:
<i data-processid="{{process.id}}" data-filename="{{process.pdf}}" class="fas fa-file-download getPdf"></i>
当你点击那个 FA 图标时,一个 AJAX POST 请求被发送到 Django 视图:
$(".getPdf").on('click', function(event) {
var thisId = $(this).data('processid');
var filename = $(this).data('filename');
$.post({
url: "{% url 'process' %}", // Points to foo.com/process
data: {
csrfmiddlewaretoken: "{{ csrf_token }}",
id: thisId
},
success: function(data) {
... handle sucess
},
error: function(data) {
... handle error
},
traditional: true
}).done();
downloadPdf(filename);
function downloadPdf(filename) {
setTimeout(function() { window.location.href = filename; }, 10000);
};
});
AJAX 函数将请求发送到后端以启动 Celery 进程以生成 PDF,然后立即调用downloadPfd
函数,该函数只是一个延迟函数,设置为(我认为是)通过 JavaScript 下载文件的方式。超时时间足以生成文件。
我找不到一个文件,即使 PDF 文件已经创建并位于主项目文件夹中(在确保它有效后,我会稍后将其移动到 Django 中的MEDIA
文件夹中。
现在,我最好通过 Django 来做这件事,这是我正在尝试的另一条路线。
在我的 Django 视图的 POST 部分,我有以下内容:(
class ProcessView(generic.DetailView):
template_name = 'pages/process.html'
def get(self, request):
# GET stuff happens
return render(request, self.template_name, {'process_form': process_form, 'process': process_list})
def post(self, request):
# Get the Process ID from the incoming request
process_id = request.POST.get('id')
# Get relevant objects and queries
... python and DB stuff ...
# Fire off a Celery task to generate the PDF file asynchronously
task = create_pdf.delay(sensor, range_period)
return HttpResponseRedirect(self.request.path_info, {"task_id": task.task_id })
该 POST 部分都有效。我点击一个按钮,它会发送 AJAX POST,该 POST 创建一个 Celery 任务,该任务会生成一个文件。我似乎无法在前端获取task_id
,即使它正在生成。
我感到困惑的部分是如何使用前端的 Celerytask.task_id
定期轮询我的 Django 视图,以检查 PDF 文件是否已生成,然后如何下载所述 PDF。我有权访问文件名和任务 ID。
我正在尝试遵循这个简短的教程,但我无法完全理解它的脚本部分(我不太擅长 JS),所以我不确定如何处理"定期检查文件是否存在,如果是,请下载它"部分,因为他似乎正在使用基于函数的视图,而我在我的项目中使用基于类的视图。
你这里有很多缺失的部分,所以我会回答第一个缺失的部分:
- 要从ajax帖子中获取task_id,您的视图应返回
JsonResponse
:
return JsonResponse({
'task_id': task_id
})
您的 javascript ajax 成功处理程序应该从通常在
success
处理程序中返回的响应中解压缩该task_id。然后,您的 JavaScript 代码应该定期轮询一个单独的 django 视图,该视图可以检索芹菜任务的结果(可能是文件名),以返回生成的 PDF 的文件名。