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>