Django, Celery: получение файла, созданного асинхронно - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть страница (foo.com/process), где вы можете создавать отчеты для данных.Иногда объем данных, которые необходимо сгенерировать, велик, поэтому требуется некоторое время.Таким образом, я поставил задачу Celery, чтобы справиться со стороной создания 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 создан и находится в основной папке проекта (я перейду позжеЯ уверен, что он работает, возможно, в папку MEDIA в Django.

Теперь мне, вероятно, было бы лучше сделать это через Django, что является еще одним маршрутом, который я пробовал.

Вкл.часть POST моего представления Django, у меня есть следующее: (

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, который создает задачу Celery, которая генерирует файл.Кажется, я не могу получить task_id на передней части, хотя он генерируется.

Часть, в которой я запутался, это как использовать сельдерей task.task_id на передней сторонепериодически опрашивать мое представление Django, чтобы проверить, был ли создан файл PDF, а затем как загрузить указанный PDF. У меня есть доступ к имени файла и идентификатору задачи.

Я пытаюсь следовать этот короткий учебникal но я не могу разобрать часть скрипта (я не очень хорош в JS), поэтому я не совсем уверен, как обрабатывать «Проверять периодически, существует ли файл, и если да,загрузить его "частично, так как он, кажется, использует представления на основе функций, а я использую представления на основе классов в своем проекте.

1 Ответ

0 голосов
/ 07 апреля 2019

У вас здесь много пропущенных фрагментов, поэтому я отвечу на первую отсутствующую часть:

  1. Чтобы получить task_id из сообщения ajax, ваше представление должно вернуть JsonResponse:

return JsonResponse({
    'task_id': task_id
})

Ваш обработчик javascript ajax success должен распаковать этот task_id из ответа, который обычно возвращается обратно в обработчик success.

Ваш код JavaScript должен регулярно опрашиватьотдельное представление django, которое может получить результат задачи сельдерея (который, предположительно, является именем файла), чтобы получить имя файла PDF, который был сгенерирован.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...