6

Done Indicator for Long Downloads of Dynamically Created Files on Django

 3 years ago
source link: https://snakeycode.wordpress.com/2020/05/21/done-indicator-for-long-downloads-of-dynamically-created-files-on-django/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Done Indicator for Long Downloads of Dynamically Created Files on Django

I frequently create files (reports) on demand on my Django sites. There is a link on the page. When the user clicks it, the Django view is called and the file is generated using code like this is run. The user remains on the page and waits for the download. If it takes more than a few seconds, then it would be nice to have some sort of busy indicator. Starting the indicator is easy. But how to stop the busy indicator when the download is done?

One solution is to use cookies (see: stackoverflow). In a nutshell, put a cookie in the Django response. When the user clicks on the link to generate the file, show “busy” indicator and start Javascript to poll for that cookie. When the cookie is found, clear it and clear the busy indicator.

Do something like this in your Django code:

from django.http import HttpResponse
response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename="my_file.xlsx"'
write_my_report(response)
response.set_cookie('my_cookie', 'done')

Then create a Javascript module for checking the cookie and doing something when it is set:

var wait_for_server_module = function(cookieName, on_done_func) {
var timer;
var getCookie = function (){
var name = cookieName + "=";
var cookies = document.cookie;
var cs = cookies.split(';');
for (var i = 0; i < cs.length; i++){
var c = cs[i];
while(c.charAt(0) === ' ') {
c = c.substring(1);
}
if (c.indexOf(name) === 0){
return c.substring(name.length, c.length);
}
}
return "";
};
var isWaitingCookie = function(){
var loadState = getCookie(cookieName);
if (loadState === "done"){
clearInterval(timer);
// Clear cookie
document.cookie = cookieName + "=clear; expires=Tue, 31 Dec 1985 21:00:00 UTC; path=/";
on_done_func();
}
};
return {
// Call this once after "is busy" is shown and server is called
lookForDone: function () {
// Make sure the cookie is cleared
document.cookie = cookieName + "=clear; expires=Tue, 31 Dec 1985 21:00:00 UTC; path=/";
// Start repeating timer
timer = setInterval(isWaitingCookie, 1000);
}
};
};

Then put something like this in your HTML:

<pre><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Page</title>
</head>
<body>
<a href="/report_url" download onclick="do_download()">download report</a>
<script src="js/wait_for_server.js"></script>
<script type="application/javascript">
var on_done_func = function(){
console.log('download is done');
}
var wait_for_server = wait_for_server_module("my_cookie", on_done_func);
var do_download = function(){
console.log('waiting');  // replace this with your busy indicator
wait_for_server.lookForDone();
}
</script>
</body>
</html></pre>

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK