Как получить индикатор выполнения при загрузке файла в Django 3.0.4 - PullRequest
1 голос
/ 04 апреля 2020

Это легко можно сделать с помощью Ajax и Jquery, но эта версия Django, кажется, делает ее более сложной. Для этого требуется '{% csrf_token%}' (без этого будет ошибка), и он автоматически отправляет файл при нажатии кнопки submit.

<form
  id="data_upload"
  method="POST"
  enctype="multipart/form-data"
  class="form-horizontal"
>
  {% csrf_token %}
  <div class="input-group mb-3">
    <div class="custom-file">
      <input
        id="file_select"
        type="file"
        class="custom-file-input"
        id="inputGroupFile02"
        accept=".csv, .xslx"
        name="file"
      />
      <label
        id="submit_label"
        class="custom-file-label"
        for="inputGroupFile02"
        aria-describedby="inputGroupFileAddon02"
        >Upload CSV or Excel file</label
      >
    </div>
    <div class="input-group-append">
      <button
        id="upload_button"
        type="submit"
        class="input-group-text btn"
        id="inputGroupFileAddon02"
        disabled
      >
        Upload
      </button>
    </div>
  </div>
  <div class="d-flex justify-content-center">
    <div
      id="loading_div"
      class="spinner-border"
      role="status"
      style="display: none;"
    >
      <span class="sr-only">Loading...</span>
    </div>
  </div>
</form>

Вот ajax

  $(document).ready(function () {
    $("#data_upload").submit(function (event) {
      event.preventDefault();
      var fd = new FormData
      fd.append('file', file_input[0].files[0])

      $.ajax({
        xhr: function () {
          var xhr = new window.XMLHttpRequest()

          xhr.upload.addEventListener("progress", progressHandler, false);
          xhr.addEventListener("load", completeHandler, false);
          xhr.addEventListener("error", errorHandler, false);
          xhr.addEventListener("abort", abortHandler, false);

          return xhr;
        },
        url: window.location.href,
        type: "POST",
        data: fd,
        processData: false,
        contentType: false,
        success: function (result) {
          alert('WOOOO!')
        },
      });
    });
  });

urls.py

urlpatterns = [
    path('upload', UploadView.as_view(), name="upload"),
]

View.py

class UploadView(TemplateView):
    def get(self, request, *args, **kwargs):
        return render(request, 'upload_datatable.html')

    def post(self, request, *args, **kwargs):
        uploaded_file = request.FILES['file']
        uploaded_file_name = uploaded_file.name

        if len(uploaded_file) != 0:
            if uploaded_file_name.endswith('.csv'):
                file_path = self.upload_csv_to_data(uploaded_file)
            elif uploaded_file_name.endswith('xlsx'):
                file_path = self.upload_excel(uploaded_file)
            else:
                return HttpResponse({'error': 'Not valid CSV or Excel'}, content_type="application/json",
                                    status_code=400)
        else:
            return HttpResponse({'error': 'No Data'}, content_type="application/json", status_code=400)

    def upload_csv_to_data(self, file):
        id = str(uuid.uuid4())
        with open(f'data/{id}.csv', 'wb+') as destination:
            for chunk in file.chunks():
                destination.write(chunk)

        return f'data/{id}'

    def upload_excel_to_data(self, file):
        id = str(uuid.uuid4())
        with open(f'data/{id}.txt', 'wb+') as destination:
            for chunk in file.chunks():
                destination.write(chunk)

        return f'data/{id}'

    def is_csv_file(self, file):
        try:
            dialect = csv.Sniffer().sniff(file.read(1024))
            file.seek(0)

            return True
        except csv.Error:
            return False

    def is_excel_file(self, file):
        try:
            book = open_workbook(file)

            return True
        except XLRDError as e:
            return False

Итак, когда я иметь функцию protectDefault, чтобы остановить Django отправку чего-либо, но когда я смотрю на сеть, ничего не отправляется, и "WOOOOO!" не печатается, и моя точка останова в Django на конечной точке POST не срабатывает. Поэтому я не думаю, что ajax отправляет файл, но в то же время я не получаю ошибок. Любой совет?

Ответы [ 2 ]

1 голос
/ 15 апреля 2020

Несмотря на то, что при удалении

    xhr: function () {
      var xhr = new window.XMLHttpRequest()

      xhr.upload.addEventListener("progress", progressHandler, false);
      xhr.addEventListener("load", completeHandler, false);
      xhr.addEventListener("error", errorHandler, false);
      xhr.addEventListener("abort", abortHandler, false);

      return xhr;
    },

не было выдано никакой ошибки, все заработало, да ...

0 голосов
/ 09 апреля 2020

Pass e.currentTarget при создании нового объекта FormData, поэтому вы включаете csrf_token в предоставленную информацию.

...
var fd = new FormData(event.currentTarget)
fd.append('file', file_input[0].files[0])
...
...