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>
|
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.
#