Django makes creating a REST API a breeze. We’ll walk you through the steps to get your first API up and operating in this tutorial.
What is the purpose of a REST API?
Before we get into the programming, think about why you’d want to create an API. We would have been so much better off if someone had taught these fundamental concepts to us before we started. A REST API is a standardized method of delivering data to other programs. The data can then be used in any way by those applications. APIs can sometimes allow other programs to make changes to the data.
For a REST API call, there are a few crucial methods:
- GET -The most common method, GET, retrieves data from the API based on the endpoint you visit and any arguments you supply.
- POST — The POST method is responsible for adding a new record to the database.
- PUT — Searches for a record at the specified URI. In addition, it updates the existing record if it exists and creates a new record if you don’t have one already.
- DELETE — Removes the record from the specified URI.
- PATCH — Modify a record’s specific fields.
An API is typically an interface to a database. The backend of the API is responsible for querying the database and formatting the answer. You get a static response of whatever resource you requested, usually in JSON format. REST APIs are so widespread in software development that understanding how they function is a must-have skill for any developer. APIs are how applications communicate with one another and even with one other.
Many web applications, for example, rely on REST APIs to allow the front end to communicate with the back end. For example, if you’re building an Angular application on top of Django, you’ll need an API that allows Angular to consume data from the database.
Serialization is the process of searching and converting tabular database values into JSON or another format. Correct data serialization is a crucial difficulty when developing an API.
What is the purpose of the Django REST Framework?
The most compelling reason to utilize the Django REST Framework is how simple serialization is! Models for your database are defined in Django using Python. So, while you can write raw SQL, the Django ORM takes care of the majority of the database migrations and queries.
from django.contrib.auth.models import User from django.db import models class CodeItem(models.Model): access_token = models.CharField(max_length=180) user = models.ForeignKey(User, on_delete=models.CASCADE)
Consider the Django ORM to be a librarian who pulls the information you need, so you don’t have to. This frees you to focus on your application’s business logic rather than the low-level implementation details as a developer. Django ORM takes care of everything.
On the other hand, the Django REST Framework works well with the Django ORM, which handles all database queryings. You may serialize your database models to REST-ful representations with just a few lines of code using the Django REST Framework.
Django to-do list for creating a REST API
So, how do we develop a REST API based on what we’ve learned?
- Step 1: Install Django
- Step 2: Create a database model that the Django ORM will manage
- Step 3: Install Django’s REST Framework
- Step 4: Serialize the model
- Step 5: To view the serialized data, create URI endpoints.
If it appears straightforward, it is. Let’s get started!
We’ll need to install Django before we can make a Django app. That’s not difficult at all!
However, it would help if you first considered building a distinct virtual environment for your project so that you may manage your dependencies independently. To accomplish this, run the following command:
The command above is responsible for creating a virtual environment with the name django_rest_env. Next, we will activate the virtual environment before installing Django. To achieve the former, run the following command.
You should be ready to install the virtual environment using pip, as shown below.
pip install Django
Let’s now create a new Django project:
$ django-admin startproject django_rest_app
We can see that Django created a new folder for us in the directory now:
And there’s everything we need to run a Django site inside that folder. Let’s double-check if it works. To do so, we will run the Django server to see how it works:
cd django_rest_app $ python manage.py runserver
In some cases, port 8000 may already be in use by another application, in which case you can stop the other app or switch to using another port. We killed the other application using the following command, which applies to Debian-based systems.
sudo kill -9 $(sudo lsof -t -i:8000)
You should see the Django welcome screen if you browse to http://127.0.0.1:8000/.
Making an API app
With the folder structure now, we may develop our application. However, when creating a new Django project, it is excellent practice to divide it into different apps. So, let’s make a new app to use with our API:
$ python manage.py startapp api_app $ ls
Registering the api_app
We need to tell Django about the new app we’ve just established. The measures we’ll take later won’t function until Django is aware of api_app. As a result, we make the following changes to django_rest_app/settings.py:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'api_app' ... # Leave all the other INSTALLED_APPS ]
Remember how we mentioned that Django allows you to create database models in Python? We must tell Django to migrate the changes to the database whenever we make or edit a model.
The Django ORM then writes all of the SQL CREATE TABLE commands. Django, it turns out, comes with a few models pre-installed. So, those built-in models must be migrated to our database. For those of you who think, “But we didn’t make a database!” You are correct. Django will construct a simple SQLite database for us if we don’t specify otherwise. SQLite is also fantastic! So, here’s how we’re going to move those initial models:
$ python manage.py migrate
Make a Super User
Before we move on, there’s one more thing. We’re about to start building some models. When we wish to review the data in our database, it would be wonderful to use Django’s attractive admin interface. We’ll need login credentials to do so. So, let’s make ourselves the project’s owners and administrators. THE ULTIMATE SUPERUSER!!!
$ python manage.py createsuperuser
Let’s make sure it works. To do so, we start the Django server by following these steps:
$ Python manage.py runserver
After that, go to localhost:8000/admin. You should see the admin dashboard after logging in with your superuser credentials. If you cannot, your superuser credentials are not correct. If that is the case with you, then redo the previous steps.
Creating a database model that Django ORM will manage
Let’s get started on our first model! We’ll make it in api_app/models.py, so go ahead and open it.
Let’s create a codeunderscored database! Each programmer has a given favorite programming language and alias in everyday life. Let’s get started with our model:
# models.py from django.db import modelsclass CodeLanguage(models.Model): name = models.CharField(max_length=60) alias = models.CharField(max_length=60) def __str__(self): return self.name
Strings are stored in the name and alias character fields. When Django needs to print an instance of the CodeLanguage model, the __str__ method tells it what to print.
Remember that every time we define or modify a model, we must tell Django to migrate the changes.
$ python manage.py makemigrations $ python manage.py migrate
Register CodeLanguage on the admin site
Remember that it is a great admin site with Django out of the box? It is unaware of the CodeLanguage model, but we can inform it of its existence with two lines of code. Make the following changes to api_app/admin.py:
from django.contrib import admin from .models import CodeLanguage admin.site.register(CodeLanguage)
Now you may start the Django server and go to localhost:8000/admin.
Creating some Code Languages
While we’re on the admin site, we might as well make some code languages to experiment with within our app. “Add” should be selected. Then go ahead and create your code languages!
Configure the Django REST Framework
Now it’s time to think about our heroes API. We need to use endpoints to serialize data from our database. We’ll need Django REST Framework, so let’s get that installed first by running the following command on the terminal.
pip install djangorestframework
Now, in django_rest_api/settings.py, notify Django that we installed the REST Framework:
INSTALLED_APPS = [ # All your installed apps stay the same ... 'rest_framework', ]
That concludes it.
Make the CodeLanguage model serial
Now we’re starting to venture into uncharted territory. REST Framework needs to know about our CodeLanguage model and data serialization. Remember that serialization is the conversion of a Model to JSON. We can use a serializer to indicate which fields should be included in the model’s JSON representation.
The serializer will convert our code languages to JSON so that the API user may parse them even if they don’t know Python. When a user POSTs JSON data to our API, the serializer converts it to a CodeLanguage model, which we can save or validate.
To do so, make a new file called api_app/serializers.py. We must include the following information in this file:
- Bring in the CodeLanguage model.
- Import the serializer from the REST Framework.
- Make a new class that connects the CodeLanguage and the serializer.
Here’s how to do it:
# serializers.py from rest_framework import serializers from .models import CodeLanguage class CodeSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = CodeLanguage fields = ('name', 'alias')
All that’s left is to connect the URLs and views to show the data! Those fundamental notions are taken to the next level with our REST API!
Let’s start with setting up the views. The various code languages are rendered in JSON format. To do so, we must:
- Look up all code languages in the database.
- Pass the database queryset through the serializer we just built, and it will be turned to JSON and rendered.
# views.py from rest_framework import viewsets from .serializers import CodeSerializer from .models import CodeLanguage class CodeViewSet(viewsets.ModelViewSet): queryset = CodeLanguage.objects.all().order_by('name') serializer_class = CodeSerializer
ModelViewSet is a unique view provided by Django Rest Framework. It will handle GET and POST for CodeLanguage without requiring additional effort.
URLs for the Site
Okay, this is fantastic already. We’re almost there. The final step is to give the viewset we just generated a URL. URLs in Django are resolved first at the project level. So, in the django_rest_api/ directory, there’s a file called urls.py. Make your way over there. In addition, you’ll notice that the admin site’s URL is already included. Now, our remaining task is to add a URL to our API. Let’s just put our API at the index for now:
# django_rest_api/urls.py from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('api_app.urls')), ]
URLs of APIs
You’ll note that we included ‘api_app.urls’ if you pay attention instead of copying and pasting. That’s the location of a file we haven’t yet created. And it’s there that Django will look for instructions on how to route this URL next. So, here’s what we’ll do next: create api_app/urls.py:
from django.urls import include, path from rest_framework import routers from . import views router = routers.DefaultRouter() router.register(r'code', views.CodeViewSet) # Wire up our API using automatic URL routing. # Additionally, we include login URLs for the browsable API. urlpatterns = [ path('', include(router.urls)), path('api-auth/', include('rest_framework.urls', namespace='rest_framework')) ]
You’ll notice that we imported something called router from rest_framework. The REST Framework router will ensure that our requests are dynamically routed to the correct resource. The URLs will update as we add or remove entries from the database.
Isn’t it cool?
To dynamically route requests, a router works with a viewset (see views.py above). A router must point to a viewset to function, and in most circumstances, if you have a viewset, you’ll want a router to go with it. Only one model+serializer+viewset has been introduced to the router so far: CodeLanguage. But, it is harmless to add more in the future by repeating the technique above for new models! Perhaps we should create a Villains API next.
Of course, urls.py will look slightly different if you only want to use regular DRF Views instead of viewsets. Simple views don’t require a router, and you can add them.
Put it to the test!
Restart the Django server as follows:
$ Python manage.py runserver
Go to localhost:8000 now.
Use the GET method to get to the endpoint
We see the exact API results if we click the link (Hyperlinks are incredible REST-ful architecture, by the way):
Fetch individual Code Language
The ID of a single model instance is used to GET it. The viewsets in the Django REST Framework take care of this for us.
You can see only one of your CodeLanguage models by going to 127.0.0.1:8000/code/id>/, where id> is the ID of one of your code languages models. For instance, for me, http://127.0.0.1:8000/code/1/ returns:
We can make this more user-friendly by including ID in the code/ endpoint response. Change the fields list in api_app/serializers.py to have “id”:
class CodeSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Code fields = ('id', 'name', 'alias')
The following is the current code language list: We can check up individual models using their IDs.
Sending a POST request to the server
Our API likewise handles post requests. We can send JSON to the API, which will create a new database record.
Django REST Framework allows you to create quick REST APIs. We hope this article has been informative. However, APIs can get complicated with several models interacting and endpoints with more advanced queries.
With that said, you’re almost done with this post. The REST Framework does an excellent job of dealing with complexity. If you get stuck, there’s a fantastic community waiting to assist you.