Archives for: February 2009
JSON response in Django views with jQuery
By Chee Ming on Feb 21, 2009 | In Random Thoughts, Technical, Exoweb, Python, Django | Send feedback »
I have been looking for a more elegant way to code and structure a Django view so that it will support rendering of responses encoded in either HTML or JSON.
I do this because I want to add some AJAXy usability to my HTML forms while retaining some backwards compatibility for non-Javascript enabled Web browsers.
First, lets look at a simple Django view:
def foo(request):
if request.method == 'POST':
form = Form1(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/foo/success/')
else:
form = Form1()
return render_to_response('app1/template1.html', {'form': form})
I was lazy and did some hacky stuff like this to support JSON response.
def foo(request):
if request.method == 'POST':
form = Form1(request.POST)
if form.is_valid():
form.save()
if request.POST.get('type', '') == 'json':
data = {} # define your own data structure
return HttpResponse(simplejson.dumps(data),
mimetype='application/json')
else:
return HttpResponseRedirect('/foo/success/')
else:
form = Form1()
return render_to_response('app1/template1.html', {'form': form})
And for the HTML form, I needed some Javascript (using jQuery) like this:
$("#id_cmd_submit").click(function(){
$.post("/foo/", {type: "json"},
function(data) {
alert(data);
}, "json");
});
I was thinking to myself that this type parameter is kinda of ugly and not necessary. The HTTP protocol actually has a Accept header that you can use to define what encoding the HTTP response from the server can be and this is automatically added when you use the $.post() from jQuery using the json type.
If you examine the HTTP headers in the Django view through request.META['HTTP_ACCEPT'] you will see values like this:
application/json, text/javascript, */*
So to make the hacky method a bit less hacky, I did this:
def foo(request):
if request.method == 'POST':
form = Form1(request.POST)
if form.is_valid():
form.save()
if 'application/json' in request.META.get('HTTP_ACCEPT', '')
data = {} # define your own data structure
return HttpResponse(simplejson.dumps(data),
mimetype='application/json')
else:
return HttpResponseRedirect('/foo/success/')
else:
form = Form1()
return render_to_response('app1/template1.html', {'form': form})
And the Javascript now looks like this:
$("#id_cmd_submit").click(function(){
$.post("/foo/", {},
function(data) {
alert(data);
}, "json");
});
Of course the code is still not very pretty and there are better ways to structure it better. In fact, all I did was just to make the API more "conforming" to HTTP and thus the Javascript code slightly cleaner. The Python code is somewhat the same.
As for the Python code, I see that someone has tried to make this style a bit prettier but I am not too sure if it will fit with all my use cases and I don't like the additional complexity.
I did read a bit about Adrian Holovaty's take on this AJAXy stuff. Its definitely cleaner than my approach but I wish Django have better support for HTTP's Accept header since I like the approach of using the Accept header. I found a middleware in Django snippets that can abstract away the complexity a bit in a more elegant way.
There is a good writeup on REST worst practices by Jacob Kaplan-Moss which touches a bit on using the Accept header instead. Malcolum Tredinnick also though on this a bit in an article about content types on this blog.
So I guess I did not bark up the wrong tree. And surprisingly, those blog articles that I found were quite recent. At least I am not outdated. ![]()
Cycling: Kuala Lumpur vs Beijing
By Chee Ming on Feb 14, 2009 | In Random Thoughts, Travel, China | Send feedback »
Happy Valentine's Day!
I wish I could spend some time with my girl but its alright because I managed to talk to her a bit over Skype. I finally went for my first proper cycling session, though short, since arriving back in KL for about a month. Today wasn't that hot so it wasn't that bad in terms of the heat. My body overheat and sweat too easily.

I took the Sprint highway from where I stayed and headed for Sri Hartamas and then Bukit Kiara to stop by at a friend's place. I did about 10km in 30 minutes when I was heading there. Not too bad for my first time. It was just a bit hilly and I am not so good yet for those hill climbs. But I realised that I had a bit more power in my legs during those nice straight paths. It could be due to the jogging sessions I have been doing for the past weeks. Coming back was much better, only 26 minutes. It could be due to the route having more downhill.
Cycling in Beijing is much more relaxed because its flat like a pan. KL goes up and down and up and down, though its mostly gradual. Another downside of cycling in KL is that it rains fairly often and although its only a drizzle, the road will spit water at you as you cycle past those patches of water. Not fun but nothing a good shower will not fix. Oh yes, I should add on mud guards, but my bike will look fugly.
Beijing has nice bike lanes and its more bike friendly. It can be dangerous cycling in KL, especially next to the highway, which is why you need a bit more planning and try to cycle on those roads with less cars and no blind corners.
Due to the lack of bicycle lanes, I have to cycle at the side of the road which is not so flat, at times and you can easily bump on to small rocks. Because of that my wrist aches a bit. So I still have a bit of getting used to, but its fun nevertheless.
I need to get proper cycling shorts and cycling shoes & pedals, when I get some extra cash on hand
.
