暇人じゃない

Django で JSON を生成して出力する

難しそうだなーと思っていましたが、実際にやってみると意外と簡単でした。

URLconf

URLconf はこんな感じになっています。 hoge.json というリクエストが来たら detail_json という view に飛ばしています。

# urls.py
urlpatterns += patterns('hogehoge.egg.views',
    url(r'^(?P<slug>[-_0-9a-zA-Z]+)\.json', 'detail_json', name='detail_json'),
)

View

View はこんな感じになっています。
オブジェクトの取得を試みて、取得できたら Django のシリアライザ(simplejson)を使用して JSON に変換。取得できなかったら MIME type を指定して 404 Not Found を出力します。
日本語のように Unicode を扱う場合は ensure_ascii=False にしておいた方が幸せになれます。
最後に生成した JSON を HttpResponse を使用し、MIME type を指定して出力、という動きになっています。

# views.py
from django.core import serializers
from django.http import HttpResponse, HttpResponseNotFound
from hashtag.tag.models import Hoge

def detail_json(request, slug):
    try:
        egg = Hoge.objects.get(name=slug)
    except Hoge.DoesNotExist:
        return HttpResponseNotFound(mimetype='application/json')

    json = serializers.serialize('json', egg, ensure_ascii=False)
    return HttpResponse(json, mimetype='application/json')

Response

出力される JSON の中身。
順不同なのが少し気になりますが…

% curl -v http://127.0.0.1:8000/hoge/azunyan.json
# (省略)
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Date: Wed, 17 Nov 2010 12:21:18 GMT
< Server: WSGIServer/0.1 Python/2.6.5
< Content-Type: application/json
<
* Closing connection #0
{"description": "\u307b\u3052\u307b\u3052\uff01", "created": "2010-11-17 21:21:01", "modified": "2010-11-17 21:21:01", "summary": "\u3042\u305a\u306b\u3083\u3093\uff01", "name": "azunyan"}

オブジェクトが取得できなければ 404 Not Found が返されます。

% curl -v http://127.0.0.1:8000/hoge/takuan.json
# (省略)
>
* HTTP 1.0, assume close after body
< HTTP/1.0 404 NOT FOUND
< Date: Wed, 17 Nov 2010 12:22:44 GMT
< Server: WSGIServer/0.1 Python/2.6.5
< Content-Type: application/json
<
* Closing connection #0