Tuesday, September 21, 2010

Ajax in django

Asynchronous Javascript and XML (Ajax) has become the most important tool for web developers in improving the look and feel of their website. A normal HTML request is sent by a client with request for a particular page. The server prepares the page and sends it to the client browser that renders the page. This approach is still valid for most pages. But the problem is that the whole page gets rendered every time the server processes a request. This might be acceptable for some websites but sites like google maps, stock ticker sites would rather modify a small portion of the page rather than reload them completely. Ajax plays an important role in such applications.

Django provides support for Ajax and my google-fu turned up a few of them that were really good. The problem I had with them was that the sites focused more on how syntactically Ajax can be executed in Django rather than the overall principle. So, in this post I will focus just on the basic principles of Ajax in Django. The anatomy of a typical django request can be summarized by the image below. The request comes in from the client, the view function processes it and the response is returned using a call to HttpResponse or render_to_response etc.



In a normal django request, the response is in the form of HTML or CSV or some such file. Ajax needs JSON or XML instead. Hence django is almost ready for Ajax. The only extra step is the need to serialize the data in to JSON or XML format. Django makes it easy by providing serializers that are builtin.

During the process of serializing, django takes two approaches. The first approach is for serializing list of django model objects and the second approach is for everything else. The everything else could include any dictionary of values that you create but need to pass through serialization. Lets look at each approach separately. Both approach are serialized using simplejson built in to django. In the former, django provides a separate module and hence you do not have to make an explicit simplejson call. In the latter, you need to make explicit calls to simplejson functions.

In the first approach, we pass the list of django model objects to the serialize function in the serializers module.


from django.core import serializers

def search(request, query):
return serializers.serialize("xml",User.objects.filter(lastname__startswith=query))


In the second approach, we need to make a explicit call to simplejson. In the program below, we first load the simplejson module. We then create our dictionary using the values, number and image_loc. We then return the json value using simplejson.dumps() function and django's HttpResponse function. The javascript on the django template will then modify the HTML page according to the values in the json object. If you use the first approach to the dictionary that you created, it will give an error, "'str' object has no attribute '_meta'"



from django.utils import simplejson

def servevalues(request):
number = 10000
image_loc = 'http://www.google.com/images/logos/ps_logo2.png'
data = {"number":number,"image_loc":image_loc}
return HttpResponse(simplejson.dumps(data),mimetype='application/javascript')



Remember:
1. Ajax calls to django are very similar to http request calls. Both return some form of textual information. Hence syntactically they look alike

2. There are 2 approach to serializing. The first approach is for django model objects and the second approach is for any other object / dictionary that you create. In either case, the code that you have to write is minimal and simple, the django way!