<p>This tutorial will walk you through the building blocks that make up REST framework. It'll take a little while to get through, but it'll give you a comprehensive understanding of how everything fits together.</p>
<h2id="getting-started">Getting started</h2>
<p>To get started, let's create a new project to work with.</p>
<pre><code>django-admin.py startproject tutorial
cd tutorial
</code></pre>
<p>Once that's done we can create an app that we'll use to create a simple Web API.</p>
<pre><code>python manage.py startapp blog
</code></pre>
<p>The simplest way to get up and running will probably be to use an <code>sqlite3</code> database for the tutorial. Edit the <code>tutorial/settings.py</code> file, and set the default database <code>"ENGINE"</code> to <code>"sqlite3"</code>, and <code>"NAME"</code> to <code>"tmp.db"</code>.</p>
<pre><code>DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'tmp.db',
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': '',
}
}
</code></pre>
<p>We'll also need to add our new <code>blog</code> app and the <code>djangorestframework</code> app to <code>INSTALLED_APPS</code>.</p>
<pre><code>INSTALLED_APPS = (
...
'djangorestframework',
'blog'
)
</code></pre>
<p>We also need to wire up the root urlconf, in the <code>tutorial/urls.py</code> file, to include our blog views.</p>
<pre><code>urlpatterns = patterns('',
url(r'^', include('blog.urls')),
)
</code></pre>
<p>Okay, we're ready to roll.</p>
<h2id="creating-a-model-to-work-with">Creating a model to work with</h2>
<p>For the purposes of this tutorial we're going to start by creating a simple <code>Comment</code> model that is used to store comments against a blog post. Go ahead and edit the <code>blog</code> app's <code>models.py</code> file.</p>
<pre><code>from django.db import models
class Comment(models.Model):
email = models.EmailField()
content = models.CharField(max_length=200)
created = models.DateTimeField(auto_now_add=True)
</code></pre>
<p>Don't forget to sync the database for the first time.</p>
<pre><code>python manage.py syncdb
</code></pre>
<h2id="creating-a-serializer-class">Creating a Serializer class</h2>
<p>We're going to create a simple Web API that we can use to edit these comment objects with. The first thing we need is a way of serializing and deserializing the objects into representations such as <code>json</code>. We do this by declaring serializers, that work very similarly to Django's forms. Create a file in the project named <code>serializers.py</code> and add the following.</p>
<pre><code>from blog import models
from djangorestframework import serializers
class CommentSerializer(serializers.Serializer):
email = serializers.EmailField()
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
def restore_object(self, attrs, instance=None):
"""
Create or update a new comment instance.
"""
if instance:
instance.email = attrs['email']
instance.content = attrs['content']
instance.created = attrs['created']
return instance
return models.Comment(**attrs)
</code></pre>
<p>The first part of serializer class defines the fields that get serialized/deserialized. The <code>restore_object</code> method defines how fully fledged instances get created when deserializing data.</p>
<p>We can actually also save ourselves some time by using the <code>ModelSerializer</code> class, as we'll see later, but for now we'll keep our serializer definition explicit.<br/>
</p>
<h2id="working-with-serializers">Working with Serializers</h2>
<p>Before we go any further we'll familiarise ourselves with using our new Serializer class. Let's drop into the Django shell.</p>
<pre><code>python manage.py shell
</code></pre>
<p>Okay, once we've got a few imports out of the way, we'd better create a few comments to work with.</p>
<pre><code>from blog.models import Comment
from blog.serializers import CommentSerializer
from djangorestframework.renderers import JSONRenderer
from djangorestframework.parsers import JSONParser
c1 = Comment(email='leila@example.com', content='nothing to say')
<p>At this point we've translated the model instance into python native datatypes. To finalise the serialization process we render the data into <code>json</code>.</p>
# '{"email": "leila@example.com", "content": "nothing to say", "created": "2012-08-22T16:20:09.822"}'
</code></pre>
<p>Deserialization is similar. First we parse a stream into python native datatypes... </p>
<pre><code>data = JSONParser().parse(stream)
</code></pre>
<p>...then we restore those native datatypes into to a fully populated object instance.</p>
<pre><code>serializer = CommentSerializer(data)
serializer.is_valid()
# True
serializer.object
# <Comment object at 0x10633b2d0>
</code></pre>
<p>Notice how similar the API is to working with forms. The similarity should become even more apparent when we start writing views that use our serializer.</p>
<h2id="writing-regular-django-views-using-our-serializers">Writing regular Django views using our Serializers</h2>
<p>Let's see how we can write some API views using our new Serializer class.
We'll start off by creating a subclass of HttpResponse that we can use to render any data we return into <code>json</code>.</p>
<p>Edit the <code>blog/views.py</code> file, and add the following.</p>
<pre><code>from blog.models import Comment
from blog.serializers import CommentSerializer
from djangorestframework.renderers import JSONRenderer
from djangorestframework.parsers import JSONParser
from django.http import HttpResponse
class JSONResponse(HttpResponse):
"""
An HttpResponse that renders it's content into JSON.
<p>It's worth noting that there's a couple of edge cases we're not dealing with properly at the moment. If we send malformed <code>json</code>, or if a request is made with a method that the view doesn't handle, then we'll end up with a 500 "server error" response. Still, this'll do for now.</p>
<h2id="testing-our-first-attempt-at-a-web-api">Testing our first attempt at a Web API</h2>
<p><strong>TODO: Describe using runserver and making example requests from console</strong></p>
<p><strong>TODO: Describe opening in a web browser and viewing json output</strong></p>
<h2id="where-are-we-now">Where are we now</h2>
<p>We're doing okay so far, we've got a serialization API that feels pretty similar to Django's Forms API, and some regular Django views.</p>
<p>Our API views don't do anything particularly special at the moment, beyond serve <code>json</code> responses, and there's some error handling edge cases we'd still like to clean up, but it's a functioning Web API.</p>
<p>We'll see how we can start to improve things in <ahref="2-requests-and-responses.html">part 2 of the tutorial</a>.</p>