Another sample of how to integrate Django and jQuery.
This starts a function in views.py that takes a long time to finish. It sets a session variable so that another function can report on the situation. We use jquery and ajax to 'pull' that data from Django so as to provide a progress report.
I don't yet know how to background a long-running process, but this is an okay stop-gap method to use. I hope.
d
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | urls.py
===
# The main url to kick it all off:
(r'^massupdate/$','scents.massupdate.views.drawMassUpdatePage'),
# Called by Ajax:
url(r'^doit/$','scents.massupdate.views.doit',name="doit"),
# Called by Ajax to pull status:
url(r'^getCount/$','scents.massupdate.views.getCount',name="getcount"),
views.py
===
from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.utils import simplejson
import time
def drawMassUpdatePage( request ):
request.session['count'] = 0
request.session['done'] = False
request.session.modified = True # May not need this.
return render_to_response("massupdate/testajax.html") # template at end
# Kicks off the update. After this starts jquery will call
# getCount periodically to 'pull' results.
def doit( request ):
# Do something long and slow
for i in range(0,5000):
request.session['count'] = i
request.session.save() # Had to do this to actually use the session in getCount.
#time.sleep(2) # Can make it even slower with this.
request.session['done'] = True
# This one is talking to a different func in the js.
return HttpResponse('All done.',mimetype='text/plain')
# This one is being pulled by $.ajax in the js.
def getCount( request ):
i = request.session.get('count', 0 ) # Fetch the count or 0
isitdone = request.session.get('done', False) # Fetch the status or False
if isitdone:
# It's all finished, so send a flag.
d= {"done":True}
j = simplejson.dumps(d)
return HttpResponse( j, mimetype='application/javascript' )
else:
# It's busy, so send a flag and a count
d= {"done":False,"count":i}
j = simplejson.dumps(d)
return HttpResponse( j, mimetype='application/javascript' )
template: testajax.html
===
<html>
<head>
<script type="text/javascript" src="/media/js/jquery/jquery-1.2.6.pack.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
// The func that calls getCount
function pull() {
// I use $.ajax. getJSON seems to cache the last data on ie6. Firefox work tho.
$.ajax ({
type: "GET",
url: "{% url getcount %}",
dataType: "json",
cache: false, //VITAL line: the getJON func does not prevent caching!
success: updater //Call this func when we have some data
})
}
// Func to use the data fetched
function updater( data, success ) {
if (data) {
// If done flag sent, say so.
if (data.done) {
txt = "DONE";
} else {
// We are busy, get the count and...
txt = data.count;
// set this to start again in 2 seconds:
window.setTimeout( pull, 2000 );
}
// Display out count/message
$('#msg').text( "SETTING TO:" + txt );
}
} //end updater
// You can start it automagically like this:
//$('#muffin').load("{% url doit %}");
//Or with an anchor
$("#go").click(function() {
$(this).hide(); // Hide the anchor
// Call doit func in Django view
$('#muffin').load("{% url doit%}");
// Start the pull function in 1 second:
window.setTimeout( pull, 1000);
});
}); //end ready
</script>
<a id="go" href="#">Start</a>
<div id="muffin">DARN</div>
<div id="msg" style="border:1px solid red;">NUMBER</div>
</body>
</html>
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 3 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
Hi,
Thank you for this code.
I just can't make it work though. I've done everything you explained but Ajax requests keeps returning 'data.count = 0' ('doit' view has not stopped). It seems like request.session is not saved afterall, is it ? I'm using Apache and no cache system set.
Any idea?
Regards, Sébastien
#
This code won't respond to a browser while its progress. A user need to wait until the following loop will be end: for i in range(0,5000):
So obviously, a user knows when it's done, but never know the progress.
We need to move this loop into a threading.
#
Please login first before commenting.