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")
  }
});