<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="setting-up-a-new-environment">Setting up a new environment</h2>
<p>Before we do anything else we'll create a new virtual environment, using <ahref="http://www.virtualenv.org/en/latest/index.html">virtualenv</a>. This will make sure our package configuration is keep nicely isolated from any other projects we're working on.</p>
<p><strong>Note:</strong> To exit the virtualenv environment at any time, just type <code>deactivate</code>. For more information see the <ahref="http://www.virtualenv.org/en/latest/index.html">virtualenv documentation</a>.</p>
<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>
<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>