How to create an easy Restful API for a simple model

How to create an easy Restful API for a simple model

In this first blog I would like to show how you can create a simple project with a restful api for a single model. The tools will be django and django rest framework. 

After you do:

pip install django

pip install djangorestframework

You may want to start by creating a new django project/app.

> django-admin.py startproject citiesprj

> cd citiesprj

django-admin.py startapp cities

Remember to add rest_framework to INSTALLED_APPS in your project settings.py

Once you got your app folder go to models and a new model City

class City(models.Model):
city = models.CharField(max_length=50)
state = models.CharField(max_length=2)
zip_code = models.CharField(max_length=10, blank=True, db_index=True)

@property
def city_state_zip(self):
return self.city + " " + self.state + ", " + self.zip_code

class Meta:
verbose_name_plural = "Cities"

def __unicode__(self):
return self.city_state_zip

In order to check that our API is working we would like to use the admin so you can go to the admin.py file and add:

from . import models

@admin.register(models.City)
class CityAdmin(admin.ModelAdmin):
list_display = ('city', 'state', 'zip_code')
search_fields = ('city', 'zip_code')
list_filter = ('state', )


Remember to run ./manage.py makemigrations and ./manage.py migrate in order to create the table for our new model. All these is well documented in https://docs.djangoproject.com/en/1.9/intro/tutorial01/

Now we are ready for our first serializer(just a class that allow us to conver to json to python and viceversa). Go to http://www.restapibuilder.com/ home page and enter the name of your model in the input box, in our case, City, then hit the button 

The you will see a div with information about the Serializer, ModelViewSet and the new url you will need in order to have your API with posting to cities and get the list of cities, get only one city and patch that city with new information based on the id of the city.

So you need to create a new file in the cities folder called serializers.py and enter this:

from rest_framework import serializers

from .models import City

class CitySerializer(serializers.ModelSerializer):
class Meta:
model = City

The in the views.py file you enter:

from rest_framework import filters, viewsets

from .serializers import CitySerializer
from .models import City

class CityViewSet(viewsets.ModelViewSet):
    model = City
    serializer_class = CitySerializer
    queryset = City.objects.all()

Finally you need to create the url that will be your endpoint for your cities API.

Add a new urls.py file in your cities app folder and type somehting like this:

from __future__ import unicode_literals

from django.conf.urls import patterns, url

from rest_framework import routers

from . import views

router = routers.SimpleRouter(trailing_slash=True)
router.register(r'cities', views.CityViewSet)
urlpatterns = patterns('',
)
urlpatterns += router.urls


We should go to our citiesprj/urls.py and add a new line for our cities urls.

url(r'^api/v1/cities/', include('cities.urls', namespace='cities')),

In order to use include you should add include to your import:

from django.conf.urls import url, include

Now we are ready to test our API. I included the api/v1 because your apis should be have version so v1 stands for version 1.

So if you run ./manage.py server you should be able to go to http://localhost:8000/api/v1/cities and test that your API is working. If you go to http://localhost:8000/admin you can test that the data is being posted correctly.

Congratulations!!! you made your first Django Rest Framework API.

Let me know if this was helpful to you.

Thanks.

PD. You could install localflavor via pip install django-localflavor and use it in models.py

from localflavor.us.models import USStateField, USZipCodeField
class City(models.Model):
city = models.CharField(max_lenght=50)
state = models.USStateField()
zip_code = models.USZipCodeField(db_index=True)

@property
def city_state_zip(self):
return self.city + " " + self.state + ", " + self.zip_code

class Meta:
verbose_name_plural = "Cities"

def __unicode__(self):
return self.city_state_zip

You can check the repo https://github.com/edilio/citiesprj in order to see a more complete sample.

Current rating: 4