How To Deploy An API With Django REST Framework In Under 30 Minutes

Offer Ben-Saadon
7 min readOct 13, 2016

--

“Hey Adam, we need to store ABC information on this website, but we need to display it over here on this other website. Can you do that? Oh, and do it fast, it needs to be done yesterday.”

Have you ever had this problem? I did.

And to me, it sounded like the job for a simple web API. Because I needed it done fast, I could not spend an entire day testing and deploying. Hmmm … That sounds like a challenge.

So, I decided to test how quickly I could write, test and deploy the API using Django REST Framework to a production server. I sat down in front of my desk and started a timer. When I hit stop, the timer read 28:50. Keep reading to find out how I was able to deploy an API so quickly in under 30 minutes.

But Wait! What Is A Web API?

For those unfamiliar, an Application Program Interface (“API”) is simply a tool to allow one piece of software to interact with another. In the context of the web, this usually means creating an endpoint that when accessed, returns a bit of JSON data. And this is what we built using Django and Django REST Framework (“DRF”).

DRF is an amazing package that allows you to get up and running with an API extremely fast. But, it is also immensely robust to build out even the most sophisticated of use cases. For our purposes, we made it more simple.

Let’s get started!

7 Simple Steps To Deploy An API Quickly

The requirements for my project were that I needed to be able to pass an unlimited number of objects, each with just a few details. As an example, in this post, we made an API about beer so we can go through the process together. Here are the steps you should take and what each object should look like.

At the end, we want a data structure that will look something like this:

[{ "title": "AHop's Spiced Ale", "url": "http://recipetavern.co/", "style": "Spiced ale" "description": "Mmmmm", }]

Step 1. Setup The Development Environment

Start by creating your base folder and cd into it:

$ mkdir ~/brewfeedproject $ cd ~/brewfeedproject

Then, setup a new virtual environment:

$ mkvirtualenv brewfeed

If you are not already using virtual environments for your python projects, I highly suggest you start right now. Believe me, it will make your life a whole lot easier!

Now, install the two required packages:

(brewfeed) $ pip install django djangorestframework

We are going to want to keep a record of the two required packages, so use pip freeze for that:

(brewfeed) $ pip freeze > requirements.txt

Start your project and your app.

(brewfeed) $ /path/to/virtualenv/brewfeed/lib/python2.7/site-packages/django/bin/django-admin.py startproject brewfeed (brewfeed) $ cd brewfeed (brewfeed) $ ./manage.py startapp beer

You will also want to setup a superuser so that you can login to the admin panel later on. Run this code and follow the steps to setup a username and password.

(brewfeed) $ ./manage.py createsuperuser

Because we are going for speed development here, we will use most of the stock Django settings untouched, including usage of an SQLite3 database. For our purposes, this will be perfectly fine. We will, however, take a look at settings.py and see what changes we will need to make to get up and running.

INSTALLED_APPS = [ ... 'rest_framework', 'beer', ]

That’s it! We are going to leave the rest untouched. Django now knows that when it is running, it needs to run our beer API app and the DRF rest_framework app.

Step 2. Create Models

We are going to keep this simple. Open /beer/models.py in your favorite text editor, mine is Sublime Text 3.

from __future__ import unicode_literals from django.db import models class FeedItem(models.Model): title = models.CharField(max_length=100, blank=True) url = models.URLField(blank=True) style = models.CharField(max_length=100, blank=True) description = models.TextField(blank=True)

Two things to note here. First, I have defined the four fields that I want in my feed to be shown here. But, I am not 100% sure that all the time, there will be information for each beer in my feed. Therefore, second, I added blank=True to each of the fields. You may be asking, but why not also null=True?

Well, for that I will refer you to the Django documentation;

Avoid using null on string-based fields such as CharField and TextField because empty string values will always be stored as empty strings, not as NULL. If a string-based field has null=True, that means it has two possible values for “no data”: NULL, and the empty string. In most cases, it’s redundant to have two possible values for “no data;” the Django convention is to use the empty string, not NULL.

For both string-based and non-string-based fields, you will also need to set blank=True if you wish to permit empty values in forms, as the null parameter only affects database storage (see blank).

Do not forget to setup your database by calling makemigrations and migrate

(brewfeed) $ ./manage.py makemigrations (brewfeed) $ ./manage.py migrate

Step 3. Create A Serializer

The serializer is the component that will take all of the information from the Django model (in this case the FeedItem) and turn it into JSON. In my experience, it is very similar to creating form classes in Django. If you have any experience in that, this will be very comfortable for you.

Inside your beer directory, create a new file called serializers.py and insert the following code:

from rest_framework import serializers from . import models class FeedItemSerializer(serializers.ModelSerializer): class Meta: model = models.FeedItem fields = ('title', 'url', 'description', 'style')

We have defined a new FeedItemSerializer that inherits the DRF ModelSerializer. We tell it to use the model; FeedItem that we just created, and that we explicitly want to use these four fields on output.

As a side note, if ever you get stuck in DRF and need a quick way to see the source code or methods and the DRF documentation is not enough, take a peak at this unofficial, yet awesome resource: Class Django REST Framework.

Step 4. Create The View

We now will turn our attention to the endpoint. How will this information be rendered to the screen? It’s easy.

from rest_framework import generics from . import serializers, models class FeedItemList(generics.ListAPIView): serializer_class = serializers.FeedItemSerializer queryset = models.FeedItem.objects.all()

Since this will be a read-only API, there is no need to get complex with any of the great utilities DRF has to offer. Instead, we will opt for the simple ListAPIView since all we need to do is create a feed of items.

All that needs to happen here is that we need to tell it to (1) use our serializer and (2) query every FeedItem in the database.

Step 5. Setup The Admin View

We need a way to save beer feed items into our database. Django makes this super easy with the default admin panel. To enable this, open beer/admin.py, and insert the following:

from django.contrib import admin from . import models class FeedItemAdmin(admin.ModelAdmin): list_display = ('id', 'title', 'url') admin.site.register(models.FeedItem, FeedItemAdmin)

We have defined a few columns that will be displayed in the table list view and enabled the form submissions for creating and editing our FeedItem.

Step 6. Add The URL

So far we have been chugging along and using vanilla Django and vanilla DRF. I am going to make one slight deviation here, and that is because I like to keep my URLs contained inside the app they belong to. For me, this structure seems neater:

brewfeed |---- brewfeed | |---- __init__.py | |---- settings.py | |---- urls.py | |---- wsgi.py |---- beer | |---- __init__.py | |---- admin.py | |---- apps.py | |---- models.py | |---- serializers.py (added by us in Step 3) | |---- tests.py | |---- urls.py (the file we are adding now) | |---- views.py

We need to do two things to make this work. Open brewfeed/urls.py and append what will be our new url patterns to the list that Django will be expecting to see.

from django.conf.urls import url from django.contrib import admin from beer import urls urlpatterns = [ url(r'^admin/', admin.site.urls), ] + urls.urlpatterns

Now, create and edit beer/urls.py.

from django.conf.urls import url from . import views urlpatterns = [ url(r'^$', views.FeedItemList.as_view()), ]

That’s it! Now we have two endpoints.

http://localhost:8000/admin will bring us into the default Django admin panel where we can make edits.
http://localhost:8000/ will display our beer feed. Don’t believe me? Give it a whirl.

Go into the admin panel using the credentials you setup at the beginning. You should now be able to add a new FeedItem. After adding a couple there, you should now be able to see the result in the feed.

Step 7 Deployment

Wow, we are almost done! The only thing left to do is launch this in the cloud and make the endpoints publically accessible.

For fast deployment of a python based project, there really is no better option in my opinion than Python Anywhere. I am not affiliated with them in any way, except to say that I have used their service on a number of occasions and they make python deployment a breeze, and even offer a free package for small test projects like this one.

Take a look at their help documentation on deploying an existing Django project. Just make sure to setup your virtual environment there too.

The bottom line…

You’re done! That was all it took. Now that you have all the code you need in front of you, I expect it to take you even less time. There you have it, A deployed web API with admin console in under 30 minutes.

What will you build?

Originally published at optymizer.com on October 13, 2016.

--

--