Получить прогресс сельдерея с помощью AJAX в Django - PullRequest
0 голосов
/ 16 октября 2019

Я новичок в веб-разработке. Я хочу загрузить файл и обработать его в задаче Celery и показать процент выполнения с помощью AJAX. Я использовал несколько примеров, например this и вот мой код:

views.py:

def importnewdata(request):

    if request.method == 'POST':
        form = RawFileAddressForm(request.POST, request.FILES)
        if form.is_valid():
            file = request.FILES['file']
            file_name = default_storage.save("sample.txt", file)
            task = process_file.delay(file_name)
            return HttpResponse(json.dumps({'task_id': task.id}), content_type='application/json')
        else:
            return HttpResponse("Error1!")
    else:

        form = RawFileAddressForm()
        return render(request, 'modelmanager/importnewdata.html', {'form': form})



def get_task_info(request):
    task_id = request.GET.get('task_id', None)
    if task_id is not None:
        task = AsyncResult(task_id)
        data = {
            'state': task.state,
            'result': task.result,
        }
        return HttpResponse(json.dumps(data), content_type='application/json')
    else:
        return HttpResponse('No job id given.')

forms.py:

class RawFileAddressForm(forms.Form):
    file = forms.FileField()

importnewdata.html:

<!DOCTYPE html>
<html>
<head>
    <title>import new raw data to db</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

</head>
<body style="text-align: center;">

    <h1>select your file to process it!</h1>
    <progress id="progress-bar" value="0" max="100" style="display:none; margin-bottom: 1em;"></progress>

    <form id="process-raw-data" action="/modelmanager/importnewdata/" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        {{  form  }}
        <input type="submit" value="Submit"/>
    </form>

<script type="text/javascript">
    var frm = $('#process-raw-data');
    var pgrbar = $('#progress-bar');

    frm.submit(function () {
        $.ajax({
            type: frm.attr('method'),
            url: frm.attr('action'),
            data: frm.serialize(),
            success: function (data) {
                if (data.task_id != null) {
                    get_task_info(data.task_id);
                }
            },
            error: function (data) {
                frm.html("error!");
            }
        });
        return false;
    });

    function get_task_info(task_id) {
        $.ajax({
            type: 'get',
            url: '/modelmanager/get-task-info/',
            data: {'task_id': task_id},
            success: function (data) {
                frm.html('');
                if (data.state == 'PENDING') {
                    frm.html('Please wait...');
                }
                else if (data.state == 'PROGRESS') {
                    pgrbar.css('display', 'inline');
                    pgrbar.val(data.result.percent);
                    frm.html('lines processed ' + data.result.current + ' out of ' + data.result.total);
                }
                else if(data.state == 'SUCCESS'){
                    pgrbar.css('display', 'none');
                    frm.html('Successfully Completed!');

                }
                if (data.state != 'SUCCESS') {
                    setTimeout(function () {
                        get_task_info(task_id)
                    }, 500);
                }
            },
            error: function (data) {
                frm.html("error!");
            }
        });
    }
</script>


</body>
</html>

Проблема заключается в том, что после нажатия кнопки «Отправить» ничего не происходит. Я получил:

"POST / modelmanager / importnewdata / HTTP / 1.1" 200 10

В Wireshark я увидел

error1!

в ответ. Это означает, что форма недействительна, но когда я удаляю часть JS из файла html, она возвращает объект json с успешно созданным идентификатором задачи сельдерея. Это означает, что форма действительна. любая помогает. спасибо.

1 Ответ

0 голосов
/ 19 октября 2019

Спасибо всем. Вы мне очень помогли! :)

Наконец, вот мое решение:

views.py:

def importnewdata(request):

    cntx = {}
    if request.method == 'POST':
        form = RawFileAddressForm(request.POST, request.FILES)
        if form.is_valid():
            file = request.FILES['file']
            file_name = default_storage.save("sample.txt", file)
            task = process_file.delay(file_name)
            cntx['task_id'] = task.id
            return render(request, 'modelmanager/importnewdata.html', cntx)
        else:
            return render(request, 'modelmanager/importnewdata.html', {'form':form})
    else:

            form = RawFileAddressForm()
            return render(request, 'modelmanager/importnewdata.html', {'form': form})

def get_task_info(request):
    task_id = request.GET.get('task_id', None)
    if task_id is not None:
        task = AsyncResult(task_id)
        data = {
            'state': task.state,
            'result': task.result,
        }
        return HttpResponse(json.dumps(data), content_type='application/json')
    else:
        return HttpResponse('No job id given.')

importnewdata.html:

<!DOCTYPE html>
<html>
<head>
    <title>import new raw data to db</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

</head>
<body style="text-align: center;">

    <h1>select your file to process it!</h1>
    <progress id="progress-bar" value="0" max="100" style="display:none; margin-bottom: 1em;"></progress>

    <form id="process-raw-data" action="/modelmanager/importnewdata/" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        {{  form  }}
        <input type="submit" value="Submit" />
    </form>

{% if task_id %}
    <script type="text/javascript">
        var taskid = "{{task_id}}";
        var frm = $('#process-raw-data');
        var pgrbar = $('#progress-bar');

        get_task_info(taskid);

        function get_task_info(tid) {
            $.ajax({
                type: 'get',
                url: '/modelmanager/get-task-info/',
                data: {'task_id': tid},
                success: function (data) {
                    frm.html('');
                    if (data.state == 'PENDING') {
                        frm.html('Please wait...');
                    }
                    else if (data.state == 'PROGRESS') {
                        pgrbar.css('display', 'inline');
                        pgrbar.val(data.result.percent);
                        frm.html('lines processed ' + data.result.current + ' out of ' + data.result.total);
                    }
                    else if(data.state == 'SUCCESS'){
                        pgrbar.css('display', 'none');
                        frm.html('Successfully Completed!');

                    }
                    if (data.state != 'SUCCESS') {
                        setTimeout(function () {
                            get_task_info(tid)
                        }, 500);
                    }
                },
                error: function (data) {
                    frm.html("error!");
                }
            });
        }
    </script>
{% endif %}


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