Done Indicator for Long Downloads of Dynamically Created Files on Django
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
>
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK