Let’s say you wanted to provide third-party application support for your web application. You’ll probably make an app that handles API calls, set up views, and compile the data you’ll be sending out in some safe format, such as JSON. You’ll also have to provide some documentation, which will complicate things further. You could all do this by hand.

Or, you could learn django-piston.

django-piston is available via pip,

pip install django-piston

Piston provides all you’ll need to make an API for your site, and it does this with as little hassle as possible. Once you have django-piston installed and inserted ‘piston’ into INSTALLED_APPS, you’ll only need to do a few more steps.

#For purposes of this guide, <myapp> is an existing app in your django application, and #<Note> is an model of <myapp>.

from django.db import models
from django.contrib.auth.models import User

class Note(models.Model):
    user = models.ForeignKey(User)
    pub_date = models.DateTimeField()
    title = models.CharField(max_length=200)
    body = models.TextField()

    def __unicode__(self):
        return self.title

1. First, make an <api> app in your system. (It can be named anything, but we use ‘api’ for simplicity.)

2. In your top-level, define a namespace for your <api> app.

urlpatterns = patterns(”,

# all my other url mappings

(r’^api/’, include(‘piston_test.api.urls’)),

# you won’t be able to use the url ‘api/’ yet until you define Resources, as is shown in step #3.

3. You’ll need a file in project_root/api/. That file should contain the following code snippet:

from piston.handler import BaseHandler
from myapp.models import Note

class NoteHandler(BaseHandler):
    allowed_methods = ('GET',)
    model = Note

    def read(self, request, id=None):
        if id:
            return Note.objects.get(pk=id)
            return Note.objects.all()

4. Finally, you’ll need to map your api/ to your handler.

from django.conf.urls.defaults import *
from piston.resource import Resource
from piston_test.api.handlers import NoteHandler

note_handler = Resource(NoteHandler)

urlpatterns = patterns('',
    url(r'^note/(?P<id>[^/]+)/', note_handler),
    url(r'^notes/', note_handler),

Notice how the urlpatterns looks only slightly changed from the norm.


Piston (django-piston) is, above all, an app. Like other well made apps, it has the following characteristics:

* Pluggable – It’s a simple matter of making an API for an existing django application, as shown by the steps described earlier.

* Self-contained – enabling or disabling the app ‘api’ would not affect the original flow of your site. You also effectively encapsulate all API related processing to that ‘api’ app.