使用 Ajax 轮询 Celery 任务

问题描述 投票:0回答:1

我有一个 Celery 任务,需要在几分钟内填充 PostgreSQL 数据库。我想在 Django 视图中从数据库中检索当前数据并将其发送到模板,该模板将根据任务的进度不断重新显示。所以,我想实时更新模板。

目前,我有一个调用 Celery 任务并获取任务结果的视图。然后它渲染模板并以字符串形式向其发送任务结果以及任务 id。

我对 AJAX 不太熟悉,但根据我所读到的内容,我需要 AJAX 调用的另一个视图来检索任务的最新结果。

这是到目前为止的代码:

渲染模板的视图:

def dashboard(request):
    result = prepare_database.delay()
    return render(request, 'appname/template.html',
                      {'task_id': result.task_id})
   

获取当前数据的视图

def current_data(request):
    task_id = request.GET.get('task_id')
    if task_id:
        async_result = AsyncResult(task_id)
        return JsonResponse({'data': async_result.get()})

Ajax 轮询任务(同样,对于 AJAX 来说非常陌生):

function pollTaskStatus(taskId) {
    $.ajax({
        url: '/current_data/',
        method: 'GET',
        data: {
            task_id: taskId  
        },
        success: function(response) {
            if (response.status === 'in_progress') {

            } else {
                // Update the HTML with the results
            }
        },
        error: function(xhr, status, error) {
        }
    });
}
$(document).ready(function() {
    var taskId = '{{ task_id }}';  // Get the task ID from the template
    pollTaskStatus(taskId);
});

如果我的整个方法有缺陷,请告诉我,因为我不太确定这是正确的方法。目前一切设置是否正确?另外,如果还有什么需要我澄清或详细说明的,请告诉我。

javascript python django ajax celery
1个回答
0
投票

您可以通过在ajax响应中提供

status
键来修改您的视图,以基于此设置条件。像下面这样:

def current_data(request):
    task_id = request.GET.get('task_id')
    if task_id:
        async_result = AsyncResult(task_id)
        if async_result.state == 'PROGRESS':
            response_data = {
                'status': 'in_progress',
                'data': 'Your code ton get data'
            }
        elif async_result.state == 'SUCCESS':
            response_data = {
                'status': 'completed',
                'data': 'Your code ton get data'  
            }
        else:
            # manage any other status if reruired
        return JsonResponse(response_data)
    return JsonResponse({'status': 'no_task'})

还可以通过设置

setTimeout()
方法在几毫秒后调用函数,通过设置定期轮询任务状态并使用最新进度数据更新模板。您可以执行如下操作:

function pollTaskStatus(taskId) {
    $.ajax({
        url: '/current_data/',
        method: 'GET',
        data: { task_id: taskId },
        success: function(response) {
            if (response.status === 'in_progress') {
                // Update the HTML with the progress data
                
                setTimeout(function() {
                    pollTaskStatus(taskId);
                }, 1000);  // Poll every 1 second
            } else if (response.status === 'completed') {
                // Update the HTML with the final results
            }
        },
        error: function(xhr, status, error) {
            console.error('Error polling task status:', error);
        }
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.