向客户端发送有关长时间运行的任务进度的更新

时间:2018-10-09 13:26:13

标签: python ajax django python-3.x django-views

我的网站上有一个页面,用户可以使用ajax上传xlsx文件,在后端,我读取了文件,进行了一些处理,然后开始逐行插入数据库中。如果用户上传的文件很大,则在数据库中输入新值可能需要一段时间。因此,我想在屏幕上为用户提供实时进度更新,例如。 -

Found 100 rows of data
Interesting 1/100.
Interesting 2/100.
...
Interesting 100/100.
Done.

我的观点:

import pandas as pd

def myView(self, request):
    """Handle POST requests, save all data provided in excel file."""
    excel_file = request.FILES.get('excel_one')
    excel_df = pd.read_excel(excel_file)
    data_format = ['Option_1', 'Option_2', 'Option_3', 'Option_4',]
    try:
        formatted_df = excel_df[data_format]
    except KeyError as error:
        return JsonResponse({'success': False, 'message': str(error), })
    # forloop to create model objects
    for i, v in formatted_df.iterrows():
        # do a lot of data validating and stuff first
        MyModels.objects.create(arguments)
        print(f'Created object {i+1}/{len(formatted_df)}!'  # Want to to be sent to html page in real time
    return JsonResponse({'success': True, })

我正在发出这样的ajax请求:

$.ajax({  // variables url, data, etc. contain the expected stuff
    async: false,
    url: url,
    method: "POST",
    data: data,
    success: function(d){
        if(data.success){
            console.log(d);
         }
         else{
             $('.log').append('<p><b>Error:</b> '+ d.message +'</p>')
         }
     },
     cache: false,
     contentType: false,
     processData: false
});

将数据保存在数据库中,其他所有功能都按预期工作,但是我不知道如何向ajax发送实时更新。我可以想到的一种可能的解决方案是实现Web套接字而不是普通的HTTP请求,但是我有点急,所以有什么方法可以用简单的js和django来实现。

2 个答案:

答案 0 :(得分:1)

如果不想使用WebSocket,可以尝试:

  • 又快又脏的方法:让您的JS轮询另一个API视图以检查状态
  • 您听说过StreamingHttpResponse吗?我从未使用过它,但可能值得尝试。您可以看到一个示例here

答案 1 :(得分:0)

Celery将为您提供任何帮助。

  • 只需为我们的耗时任务编写一个函数,并将其设置为芹菜任务
  • 立即返回进程ID或文件,作为第一个API的响应
  • 从具有该ID的ur ajax的第二个API上进行轮询,以获取该API上的预期结果

请注意:打开HTTP请求的时间不要超过特定时间,这会严重影响性能。