Django & AJAX загрузка файлов

При использовании запроса POST с AJAX в Django 4.0.1 я не могу получить файл из бэкенда, используя request.FILES. Используемая форма довольно простая, поэтому я не могу заметить никаких опечаток и т.д.

HTML:

<form id="snipForm" method="POST" enctype="multipart/form-data">
  {% csrf_token %}
      <input type="file" id="multiFiles" name="files[]" multiple="multiple"/>
      <button id="upload">Upload</button>
</form>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

JavaScript: (извините за довольно длинный пример кода, но я не могу сократить его больше)

$(document).ready(function (e) {
  $('#upload').on('click', function (event) {
    //Prevent page from reloading
    event.preventDefault()
    var form_data = new FormData();
    // check if there is any file selected
    var ins = document.getElementById('multiFiles').files.length;
    if(ins == 0) {
      $('#msg').html('<span style="color:red">Select at least one file</span>');
      return;
    }
    // add all files
    for (var x = 0; x < ins; x++) {
      form_data.append("files[]", document.getElementById('multiFiles').files[x]);
    }
    // obtain CSFR token
    csrf_token = $('input[name="csrfmiddlewaretoken"]').val();

    // set the headers
    headers = {'HTTP_X_REQUESTED_WITH': 'XMLHttpRequest', 'X-CSRFToken': csrf_token};

    $.ajax({
      type: 'POST',
      url: '/docs/', // point to server-side URL
      dataType: "json",
      ContentType: "application/x-www-form-urlencoded",
      cache: false,
      processData: false,
      headers: headers,
      data: form_data,
      success: function (response) { // display success response
        console.log("successssssssssssss")
      },
      error: function (response) {
        console.log("NOPEEEEEE")
      }
    });
  });
});

views.py:

from django.views.decorators.csrf import ensure_csrf_cookie

@ensure_csrf_cookie
def generate(request):
    is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
    if request.method == 'POST' and is_ajax:
        files = request.FILES.getlist('files[]')
        if files:
            print("file here")
            #do some stuff
        else:
            print("NO FILE AT ALL")
        return JsonResponse({...})

Сам запрос, похоже, работает console.log('sucessss') после завершения запроса становится видимым. Однако Django не имеет доступа к файлу. Данные с хранимым файлом сохраняются в form_data, но, насколько я знаю, мы можем получить доступ к файлам через упомянутые request.FILES['name_of_the_input'].

Что может быть причиной?

При выполнении загрузки файла (с FormData) с помощью $.ajax, вы должны установить contentType и processData в false.
. Иначе jQuery попытается преобразовать ваш объект FormData в строку и установить тип содержимого запроса "application/x-www-form-urlencoded", что неверно.
Правильный тип содержимого - multipart/formdata и будет установлен автоматически.

$.ajax({
  type: 'POST',
  url: '/docs/', // point to server-side URL
  dataType: "json",
  cache: false,
  contentType: false,
  processData: false,
  headers: headers,
  data: form_data,
  success: function (response) { // display success response
    console.log("successssssssssssss")
  },
  error: function (response) {
    console.log("NOPEEEEEE")
  }
});
Вернуться на верх