Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add file upload progress bar to Django website

I am trying to use django-progressbarupload app to add progress bar to my Django app. But it is not working .... The django-progressbarupload app templates tags are loading fine and also file is uploading to the server but progress bar is not showing up ...and their is no javascript error on the console... I have followed this tutorial

Can anyone tell how to add progress bar to Django app

like image 939
Vaibhav Jain Avatar asked Nov 17 '25 16:11

Vaibhav Jain


1 Answers

It's not the best solution (and not so consistent) but it will be the easiest to implement.

Create js file e.g. progress_bar.js

In your admin.py

class YouSuperModelAdmin(admin.ModelAdmin):
    ...
    class Media:
        js = ['/static/js/progress_bar.js']
    ...

In progress_bar.js

(function($){   
$(function(){
    $(document).ready(function() {
        $( "#form_id" ).submit(function( event ) {
          event.preventDefault();

          var post_data = new FormData($("form")[0]);

          $.ajax({
              xhr: function() {
                var xhr = new window.XMLHttpRequest();
                var new_div = document.createElement('div');

                new_div.innerHTML = '<progress id="progressBar" value="0" max="100" style="width:300px;"></progress><h3 id="status"></h3><p id="loaded_n_total"></p>';
                document.getElementsByClassName('submit-row')[0].appendChild(new_div)

                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,// to allow add and edit
                type: "POST",
                data: post_data,
                processData: false,
                contentType: false,
                success: function(result) {
                    window.location.replace("/admin/yourapp/yoursupermodel/");
              }
            });
        });
    });
});  
})(django.jQuery);

The idea is to prevent default form submition, create new XMLHttpRequest, inject progressbar with messages and then send the data showing the process.

It is very important to set processData: false, contentType: false, otherwise it will not handle the file in the form

And finaly in your progress_bar.js set event handlers for the progress bar itself.

function _(el) {
  return document.getElementById(el);
}

function progressHandler(event) {
  _("loaded_n_total").innerHTML = "Uploaded " + event.loaded + " bytes of " + event.total;
  var percent = (event.loaded / event.total) * 100;
  _("progressBar").value = Math.round(percent);
  _("status").innerHTML = Math.round(percent) + "% uploaded... please wait";
}

function completeHandler(event) {
  _("status").innerHTML = event.target.responseText;
  _("progressBar").value = 0; //wil clear progress bar after successful upload
}

function errorHandler(event) {
  _("status").innerHTML = "Upload Failed";

}

function abortHandler(event) {
  _("status").innerHTML = "Upload Aborted";
}

NOTE: In order not to have html page appearing under the form after success you have to change your view that returns HttpResponse object or simply change the window.location.

The described method should work for any form with django.

like image 175
urDMG Avatar answered Nov 20 '25 07:11

urDMG



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!