Build a Django API Under 10 Minutes ⚡

Subscribe to my newsletter and never miss my upcoming articles

Django is always been one of my favourite language of all time, there can be lots of reason like:

  1. Most popular framework
  2. Designed to provide Rails-like ease of use
  3. Everything is in object
  4. Popular Database connection
  5. Scalability
  6. Security out of the box
  7. Robust Server connection
  8. Popular log connectivity .. and many more.

In this tutorial let's see how quickly we can set up a simple API using Django and a Library called TastyPie.

Note: I am not going to use DRF here and the DRF part will cover in a later tutorial, I just wanted to build an API without DRF help. Hope you like it.

Wish to build

We're going to build an API for a Notetaking web app. We will be building a REST-ful API with CRUD endpoints.

The good news is that rather than approach these endpoints individually, Django lets us more or less create them all in one fell swoop.

Setting Up Project

Django divides your work into projects and apps. Projects contain apps, but apps do not necessarily belong to a certain project — the idea is to make them reusable across projects.

We’ll only be making one app within one project, but the file structure may seem a little odd if you don’t keep this in mind.

Install Django and create our project:

pip install Django
django-admin startproject note_django
cd note_django

Next, we’ll install TastyPie, which will supply us with a REST framework.

pip install django-tastypie

Finally, we can start our app within our project:

python manage.py startapp api

Before we go on, we have to install our app within our project, inside note_django/settings-py:

# note_django/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'api'
]

Again, our project can have multiple apps installed — and those apps aren’t necessarily tied to that project.

Model

The first thing we need to create is a Note model to interact with.

Django is unique (compared to a framework like Ruby on Rails) in that your migrations follow how you define your models, rather than being separately defined.

Let’s create our model, in api/models.py

# api/models.py
class Note(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
        return self.title

Okay, our model is all set up. Now to run our migrations, which will set up our database.

python manage.py makemigrations
python manage.py migrate

Let’s go ahead and populate our database with a single note, to make sure all is well:

python manage.py shell
>>> from api.models import Note
>>> note = Note(title="First Note", body="This is certainly noteworthy")
>>> note.save()
>>> Note.objects.all()
<QuerySet [<Note: First Note This is certainly noteworthy>]>
>>> exit()

API-ification

Okay, so our model and database are all ready to go. Now to expose some endpoints to the wider world, so we can interact with our data.

One of the basics of RESTful APIs is the idea of resources. The term is rather abstract, but in this context, it refers to a class that sits between our URLs and our models.

A user will make a request to an endpoint. Depending on the URL, the user will be redirected to a particular resource, which will then perform the appropriate CRUD action on the model.

Again, this is a simplified explanation of a complex topic — let’s go ahead and see it in practice:

In your API folder, create a new file called resources.py.

# api/resources.py
from tastypie.resources import ModelResource
from api.models import Note
class NoteResource(ModelResource):
    class Meta:
        queryset = Note.objects.all()
        resource_name = 'note'

We import our model and create a resource from it. The queryset (what models the resource is concerned with) is all note objects.

We also name the resource appropriately: ‘note’. This will be important for URLs.

Speaking of which, let’s set those up in our note_django/urls.py file:

from django.conf.urls import url, include
from django.contrib import admin
from api.resources import NoteResource
note_resource = NoteResource()
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^api/', include(note_resource.urls)),
]

We import our NoteResource, instantiate it, and then say that we want all URLs that start with api/ to redirect to the resource. (Don’t forget to import include from django.conf.urls).

Test API

Finally, we can get running. As in the Node tutorial, we’re going to use Postman to make API requests.

python manage.py runserver

Now in Postman, let’s send a GET request to this URL: http://localhost:8000/api/note/1

1_8Paypbwf_k8z-csMl2xpVw.png

Great! Our GET endpoint is working perfectly. Easy.

Also make sure you send the request to http://localhost:8000/api/note/, not http://localhost:8000/api/note. That trailing slash is important since otherwise, Django has to redirect you, losing the POST data.

Send that request and… it fails. We get back a 401, AKA Unauthorized.

It’s an easy fix, though — import their basic Authorization class and add it to our resource.

# api/resources.py
from tastypie.resources import ModelResource
from api.models import Note
from tastypie.authorization import Authorization
class NoteResource(ModelResource):
    class Meta:
        queryset = Note.objects.all()
        resource_name = 'note'
        authorization = Authorization()

Now it works! Try the request, and we get back 201, AKA success!

Final Notes

Thanks for reading. This is an old tutorial that I have tried without using the Django Rest Framework and it doesn't disappoint at all. 😎️

No Comments Yet