Как обрабатывать три функции с помощью celery в django?

У меня есть три функции в моих представлениях сайта django, но я могу запустить только одну. Я никогда не использовал celery, можете ли вы помочь мне преобразовать это в задачи celery?

Как вы видите, я хочу сохранить документ, загруженный пользователем, затем я хочу сделать некоторые вещи pandas с этим файлом, и после этого я хочу показать вещи pandas на html-странице.

Это forms.py

class DocumentForm(forms.Form):
    docfile = forms.FileField(label='Select a file')

Это views.py

def save_exls(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            newdoc = Document(docfile=request.FILES['docfile'])
            newdoc.save()
            return redirect('html_exls')
    else:
        form = DocumentForm()
    documents = Document.objects.all()
    context = {'documents': documents, 'form': form,}
    return render(request, 'list.html', context)


def pandas_exls(request):
    if request.method == "POST":
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            output = io.BytesIO()
            newdoc = request.FILES['docfile']
            dfs = pd.read_excel(newdoc, sheet_name=None, index_col=[0])
            writer = pd.ExcelWriter(output)
            for name, df in dfs.items():
                #pandas stuff
                done.to_excel(writer, sheet_name=name)
            output.seek(0)
            response = HttpResponse(
                output, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            response['Content-Disposition'] = 'attachment; filename=%s' % filename
            return response
    else:
        form = DocumentForm()
    return render(request, 'list.html', {'form': form})


def html_exls(request):
    if request.method == "POST":
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            output = io.BytesIO()
            newdoc = request.FILES['docfile']
            dfs = pd.read_excel(newdoc, sheet_name=None, index_col=[0])
            writer = pd.ExcelWriter(output)
            for name, df in dfs.items():
                #pandas stuff for html 
                done.to_excel(writer, sheet_name=name)

            html = done.to_html()
            print(html)
            output.seek(0)
            response = HttpResponse(
                output, content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
            response['Content-Disposition'] = 'attachment; filename=%s' % filename
            return response
    else:
        form = DocumentForm()
    return render(request, 'list.html', {'form': form})

Это html-файл, list.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Django site</title>
    </head>

    <body>

        <!-- Upload form. Note enctype attribute! -->
        <form action="{% url "pandas_exls" %}" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <p>{{ form.non_field_errors }}</p>

            <p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>

            <p>
                {{ form.docfile.errors }}
                {{ form.docfile }}
            </p>

            <p><input type="submit" value="Upload"/></p>
        </form>
        <br/>
            {{html|safe}}
        

    </body>
</html>

не логично запускать render returning function views в задачах celery. вам нужно использовать render to string и js, чтобы это произошло. вам буквально не нужен celery. и я не понимаю, почему вы пытаетесь сгенерировать новую форму в 3 разных представлениях на одной html-странице? вы загружаете новые файлы или что-то в pandas и html представлениях

Я использую для этого task_api, это проект django, который отслеживает функции и предоставляет некоторый javascript для опроса бэкенда на предмет изменений и обновлений, когда функции закончат выполняться. Он пока не поддерживает параметры файлов, но вы можете сначала сохранить файл, а затем на javascript вызвать следующий метод для работы с этим файлом после сохранения и отображения прогресса.

Я бы написал 3 конечные точки, 1 для загрузки файла, используя форму, затем 1 конечная точка ajax, которую вы вызываете на javascript для обработки файла, она вернется, когда все будет готово, и тогда вы сможете перенаправить на 3-ю конечную точку, которая загрузит файл.

например. views.py

и в вашем list.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Django site</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="{% static 'django-task-api.min.js' %}"></script>
    <script type="text/javascript">
        function runtask(task, documentid, progressdivname) {
            TaskAPI.run(task, documentid, function(json) {
                if (json.target === null || json.progress === null) {
                    return false
                }
                document.getElementById(progressdivname).innerHTML = 'Progress: ' + json.progress + ' / ' + json.target
            })
            .then(function(json) {
                # panda's is done, download doc
                window.location = '/download/' + json.outputs.documentid;
    })
            return false
        }

$(document).ready(function (e) {
 $("#form").on('submit',(function(e) {
  e.preventDefault();
  $.ajax({
         url: "/upload",
   type: "POST",
   data:  new FormData(this),
   contentType: false,
         cache: false,
   processData:false,
   beforeSend : function()
   {
    //$("#preview").fadeOut();
    $("#err").fadeOut();
   },
   success: function(documentid)
      {

     // process uploaded file.
runtask('pandas', {'documentid': documentid}, 'progress')
    }
,
     error: function(e) 
      {
    $("#err").html(e).fadeIn();
      }          
    });
 }));
});
    </script>

    </head>

    <body>

        <!-- Upload form. Note enctype attribute! -->
        <form action="{% url "pandas_exls" %}" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <p>{{ form.non_field_errors }}</p>

            <p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>

            <p>
                {{ form.docfile.errors }}
                {{ form.docfile }}
            </p>

            <p><input type="submit" value="Upload"/></p>
        </form>
        <br/>
        <div id="progress"></div>
        

    </body>
</html>
Вернуться на верх