javascriptdjangoajaxdjango-rest-frameworkjquery-upload-file-plugin

File uploading using AJAX is not working in Django


I'm trying to upload file using onchange event and AJAX but it is not working. I'm getting file path on backend not actual file. I want to modify this code such that when pdf file selected the file automatically get uploaded and can be use in views.py.

a.html:

<html>
  <head>
     <title> Django image and file upload using ajax </title>
  </head>
<body>
   <form enctype="multipart/form-data" id="id_ajax_upload_form" method="POST" novalidate="">
     {%csrf_token%}
      <input type="file" id="resumes" onchange="funct()" name="resumes">
       <span>File</span>
      <input type="file" id="file" name="file" size="10"/>
      <input id="uploadbutton" type="button" value="Upload"/>
   </form>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
   <script>
   src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
  </script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script type="text/javascript">
   function getCookie(name) {
       var cookieValue = null;
       if (document.cookie && document.cookie != '') {
           var cookies = document.cookie.split(';');
           for (var i = 0; i < cookies.length; i++) {
               var cookie = jQuery.trim(cookies[i]);
               // Does this cookie string begin with the name we want?
               if (cookie.substring(0, name.length + 1) == (name + '=')) {
                   cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                   break;
               }
           }
       }
       return cookieValue;
   }
   var csrftoken = getCookie('csrftoken');
   function csrfSafeMethod(method) {
       // these HTTP methods do not require CSRF protection
       return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
   }
   $.ajaxSetup({
       beforeSend: function(xhr, settings) {
           if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
               xhr.setRequestHeader("X-CSRFToken", csrftoken);
           }
       }
   });
   $(document).ready(function(){
     $("#file").change(function(){
       var filename = $("#file").val();
       $.ajax({
           type: "POST",
           url: "",
           enctype: 'multipart/form-data',
           data: {
               file: filename,
           },
           success: function () {
               // alert("Data Uploaded: ");
           }
       });
     })
   })

  </script>
</body>
</html>

Views.py:

def django_image_and_file_upload_ajax(request):
    if request.method == 'POST':
        print("working..............")
        print(request.POST.get('file'))
        print(request.FILES.get('file'))
        print(request.FILES.getlist("file"))
        print("...................................................")
        print(request.POST.get('data'))
        print(request.FILES.get('data'))
        print(request.FILES.getlist("data"))
        return JsonResponse({'error': False, 'message': 'file'})
    return render(request, 'a.html')

Console output on selecting a file:

System check identified no issues (0 silenced).
December 08, 2020 - 06:55:41
Django version 3.1.3, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Not Found: /
[08/Dec/2020 06:55:46] "GET / HTTP/1.1" 404 2131
Not Found: /favicon.ico
[08/Dec/2020 06:55:46] "GET /favicon.ico HTTP/1.1" 404 2182
[08/Dec/2020 06:55:51] "GET /URL1/upload/ HTTP/1.1" 200 2318
working..............
C:\fakepath\dummy3.pdf
None
[]
...................................................
None
None
[]
[08/Dec/2020 06:56:09] "POST /URL1/upload/ HTTP/1.1" 200 35

How can I get file on backend?


Solution

  • You can post the files as form data as below :

    var formData = new FormData();
    formData.append('file', $('#file')[0].files[0]);
    
    $.ajax({
       url : 'your_url',
       type : 'POST',
       data : formData,
       enctype: 'multipart/form-data',
       processData: false,
       contentType: false,
       success : function(data) {
           # success
       }
    });