Previous topic

Blog Posts API

Next topic

Object Store API

This Page

Getting Started - Model ViewsΒΆ

Note

A live sandbox instance of this API is available:

http://rest.ep.io/model-resource-example/

You can browse the API using a web browser, or from the command line:

curl -X GET http://rest.ep.io/resource-example/ -H 'Accept: text/plain'

Often you’ll want parts of your API to directly map to existing django models. Django REST framework handles this nicely for you in a couple of ways:

  1. It automatically provides suitable create/read/update/delete methods for your views.
  2. Input validation occurs automatically, by using appropriate ModelForms.

Here’s the model we’re working from in this example:

models.py

from django.db import models

MAX_INSTANCES = 10


class MyModel(models.Model):
    foo = models.BooleanField()
    bar = models.IntegerField(help_text='Must be an integer.')
    baz = models.CharField(max_length=32, help_text='Free text.  Max length 32 chars.')
    created = models.DateTimeField(auto_now_add=True)

    def save(self, *args, **kwargs):
        """
        For the purposes of the sandbox limit the maximum number of stored models.
        """
        super(MyModel, self).save(*args, **kwargs)
        while MyModel.objects.all().count() > MAX_INSTANCES:
            MyModel.objects.all().order_by('-created')[0].delete()

To add an API for the model, first we need to create a Resource for the model.

resources.py

from djangorestframework.resources import ModelResource
from djangorestframework.reverse import reverse
from modelresourceexample.models import MyModel


class MyModelResource(ModelResource):
    model = MyModel
    fields = ('foo', 'bar', 'baz', 'url')
    ordering = ('created',)

    def url(self, instance):
        return reverse('model-resource-instance',
                       kwargs={'id': instance.id},
                       request=self.request)

Then we simply map a couple of views to the Resource in our urlconf.

urls.py

from django.conf.urls.defaults import patterns, url
from djangorestframework.views import ListOrCreateModelView, InstanceModelView
from modelresourceexample.resources import MyModelResource

my_model_list = ListOrCreateModelView.as_view(resource=MyModelResource)
my_model_instance = InstanceModelView.as_view(resource=MyModelResource)

urlpatterns = patterns('',
    url(r'^$', my_model_list, name='model-resource-root'),
    url(r'^(?P<id>[0-9]+)/$', my_model_instance, name='model-resource-instance'),
)

And we’re done. We’ve now got a fully browseable API, which supports multiple input and output media types, and has all the nice automatic field validation that Django gives us for free.

We can visit the API in our browser:

Or access it from the command line using curl:

 #  Demonstrates API's input validation using form input
 bash: curl -X POST --data 'foo=true' http://rest.ep.io/model-resource-example/
 {"detail": {"bar": ["This field is required."], "baz": ["This field is required."]}}

 #  Demonstrates API's input validation using JSON input
 bash: curl -X POST -H 'Content-Type: application/json' --data-binary '{"foo":true}' http://rest.ep.io/model-resource-example/
{"detail": {"bar": ["This field is required."], "baz": ["This field is required."]}}