Django большой экспорт CSV с помощью celery (async)

Я пытаюсь экспортировать CSV-файл, на создание которого уходит много времени. Я написал представление экспорта CSV, которое успешно работает, однако мне нужно было адаптировать его для использования celery, чтобы оно работало в производстве с большими объемами данных. Я написал следующий код (в основном следуя https://thoslin.github.io/async-download-with-celery/):

Вид:

from tasks import export_report
@staff_member_required()
def export_status_report(request):
    task = export_report.delay()
    return render(request, "admin/poll_for_download.html", {"task_id": task.task_id })

# Check if task is finished
def poll_for_download(request):
    task_id = request.GET.get("task_id")
    filename = request.GET.get("filename")

    if request.is_ajax():
        result = AsyncResult(task_id)
        if result.ready():
            return HttpResponse(json.dumps({"filename": result.get()}))
        return HttpResponse(json.dumps({"filename": None}))

    try:
        f = open("/path/to/export/"+filename)
    except:
        return HttpResponseForbidden()
    else:
        response = HttpResponse(file, mimetype='text/csv')
        response['Content-Disposition'] = 'attachment; filename=%s' % filename
    return response

Задача:

@app.task
def export_report():
    date = datetime.now()
    date = date.strftime("%m/%d/%Y")
    filename = "reoport"+date+".csv"
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename= "{}"'.format(filename)
    payouts = Payout.objects.all()

    writer = csv.writer(response) #instantiate writer

    # write headers
    writer.writerow(['Field1', 'Field2', 'Field3'])

    for payout in payouts:
        list = [payout.field1, payout.field2, payout.field3]
        writer.writerow(list)

    return filename

HTML

<script>
$(function(){
    $.ajaxSetup({ cache: false, timeout: 360000 });
    var url = "admin/poll-for-download/";
    var i = 0;
    (function worker() {
        $.getJSON(url+"?task_id=", function(data){
            if(data.filename) {
                var file_url = url+"?filename="+data.filename;
                $("#content").html("If your download doesn't start automatically, please click <a href='"+file_url+"'>here</a>.");
                window.location.href = file_url;
            } else {
                setTimeout(worker, 5000);
            }
        });
    })();
    setInterval(function() {
        i = ++i % 4;
        $("#loading").html("loading"+Array(i+1).join("."));
    }, 1000);
});

Однако это не работает. Я получаю ошибку:

with open("%s%s" % ("/path/to/export/", filename), "w+") as f:
2022-11-10T14:03:49.564942+00:00 app[worker.1]: FileNotFoundError: [Errno 2] No such file or directory: '/path/to/export/31e39843-421d-49f5-8a59-46394c22a3ce.csv'

Как мне исправить это, чтобы скрипт автоматически загружал CSV, когда он будет готов, и предоставлял ссылку пользователю, в случае если загрузка не начнется автоматически. Я также не хочу, чтобы отчеты были общедоступны, поэтому они не должны загружаться в нашу статическую папку S3/Cloudfront.

заменить file

Задача response = HttpResponse(file, mimetype='text/csv')

с

response = HttpResponse(filename, mimetype='text/csv') или f файловый объект

Вернуться на верх