Creating a Django API using Django Rest Framework APIView

“two black flat screen computer monitors” by Fotis Fotopoulos on Unsplash

An API(Application Programming Interface) is a software that allows two applications to talk to each other. In this blog, we will be creating an API that allows clients to create and read articles just like Medium blog post. We will explore different ways to create a Django Rest Framework(DFR) API in a 3 part series starting with a plain APIView(PART 1) then using GenericAPIView(PART 2) and finally using ViewSets(PART 3).

The final source code of what we will be creating can be found on GitHub .
I will also be using pipenv for my development environment management i.e things like creating a virtual environment and installing packages.

So in the terminal, create a directory and give it any descriptive name; I will name mine MediumClone. mkdir MediumClone is the command to use for the above process. Next, cd into the project folder that you have created and install Django by typing

pipenv install django
You should be having these files now in your folder.

Since we will be using Django Rest Framework (DRF) for creating the API, go ahead and install it into your virtual environment the same way we did it above.

pipenv install djangorestframework

Now we are ready to create our first DRF API.

We need to create a Django project to work with. For this, we run the command

django-admin startproject yourprojectname

Next we apply the database migrations by running

python mange.py migrate

and finally, run the server to ensure everything is intact; Do this by running

python manage.py runserver

With this, we now have a Django project where we can integrate our Django rest framework. Open your settings.py and in the installed apps add rest_framework in quotes. With this, we are ready for the next step.

Having set up the project, it is time to start creating an app for our project. We will create an articles app where we will house everything related to an article .

python manage.py startapp article

is the command we will use to create the app. Navigate to models.py file where we will be creating our models from.

models.py Location

Start by creating the following models

Author model

Then the article models

Article Model

Now, create a superuser

python manage.py createsuperuser

and login to the admin page.

What you should see.

Next, let's register our models in order for them to appear on this page.
To do this, we open the admin.py file inside the articles folder and register the models as shown below

Now its time for us to create our endpoints.
We will start with an endpoint where we can view all articles. For this, open views.py and paste the following code

get method for all articles.

Next, we need to provide a URL from where a user will be able to access this endpoint. For that, create a urls.py file inside the articles folder. In this file, paste the following code.

Next, we need to include these URLs inside the main URLs file i.e the URLs shown below

These will be in the folder named as your project.

To include our URLs from the articles app to the main URL Configuration, we will use the include Django method.

Now every time we go to http://127.0.0.1:8000/api/ , we should be able to access all the URLs that we define inside the articles/urls.py i.e we can do something like http://127.0.0.1:8000/api/articles/ . Try this out and see the response.

Response from my end.

So far, we have been able to create a working endpoint from which we can view all articles in the database give yourself a pat on the back for coming this far.

We currently have no articles in our database thus the response we get is an empty list. One of the reasons we added our Article and Author to the admin page was to be able to add Authors and Articles directly to our database through the admin page. Proceed and add an Author and an Article from the admin page.

http://127.0.0.1:8000/admin/article/author/add/
http://127.0.0.1:8000/admin/article/article/add/

After adding one or more authors and articles, you realize they are displayed in a not very pleasing way

Article object(1)

Article object(1) isn’t very descriptive. Let's change this to be something like the name of the article. To do this, we need to go back to our models.py and add a method called __str__ ; It is the method that gives us a readable representation of an object in our case Article Object.

On adding the above method in my Article class, here are the new results

Add the same method to the Author class to get the same effect.

Now that we have some Articles in the database, let's see if our assets endpoint is working. Navigate to http://127.0.0.1:8000/api/articles

Ohhh no!!!

TypeError

TypeError. Seriously? After all this work? Don’t be disappointed yet.
The error is being raised by this line return Response({"articles": articles}) the list of articles is trying to be serialized/converted from an object into JSON. Since we haven’t provided a class to serialize the Article object, we receive the above error.

To fix this, I will introduce you to Serializers .

Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON, XML or other content types.

Since now we know what serializers are, let's create one that will convert our articles to a python list that we can return to our users.
Create a new file inside articles folder and name it something like serializers.py . In this file, add the following code.

As you can see we are not serializing the user for now. That will come later.
The next step is to add this serializer to our views and ask the view to serialize the articles. The following code shows how this is done.

With this, run your server again and navigate to http://127.0.0.1:8000/api/articles/ . From my side, the following is the response I received

It Works!

We don’t want to limit creating articles from the admin dashboard since not every user has the admin rights. To overcome this challenge, we can create an endpoint where users will be able to create articles from. We could create another class with a post method and register it into our URLs just like we did for the get method. However, instead of creating a brand new class and an endpoint, APIView allows us to specify multiple HTTP methods for that class. We will, therefore, add a post method inside of our ArticleView check out the code below.

As you can see, we are using the serializer that we created earlier in order to create an article from the article data we receive from the users. As we had said earlier, we had ignored the author's field in our serializer and thus it was not being returned in the response we got. For us to be able to use our serializer to create articles, we need to add the author_id field into the serializer and then we will need to implement thecreate method in the serializer that tells the serializer what to do when the serializer save method is invoked.
Update your ArticleSerializer to look like this.

Given that you had created an author from the admin dashboard, you can now use postman or any other client to create an article. An example of such a request is shown below.

sample article.

With that, anyone can now be able to create articles from the endpoint. We currently allow anyone to create articles into our database; We will fix this later on.

What happens when someone creates an article with a typo in the article or the description? Will they have to create a new article? The answer is no. A user should be able to update articles.

For this, we will update our articles endpoint to allow users to update an article by sending a PUT request to the article. First, add a new path in the articles urlpatterns from which the update will be sent to.

path('articles/<int:pk>', ArticleView.as_view())

Next, let's add an update method to our serializer that will do the update for us. Your code now should look like the following

serializer.py

What is happening in the update method is that we are passing in the instance of the article we want to update and if the user has provided a value to update with, we reassign that value otherwise we maintain the old value of the attribute.

Now let’s work on getting the update request from the user and updating the article. First, we have to define the put method in our ArticleView , this method should accept a pk URL parameter which we will use to query the Article we want to update. Here is how the put method should look like.

We are passing partial=True to the serializer since we want to be able to update some fields but not necessarily all at once. 
Using Postman or any other tool, you can now be able to update an article by sending a put request to the URL http://127.0.0.1:8000/articles/<article id> with the data you want to update.

Great progress so far. Now, suppose you decide you don’t want this article anymore?? 
In the last part of this blog, we are going to add a delete functionality to our API. For this, we will create a delete method in the APIView that takes the id of the article we want to delete as an argument.

For the delete method, all we are doing is getting the article if it exists and then deleting it and returning a response to the user.

With this, we have a functioning API where we can perform all the basic requirements of an API i.e CreateReadUpdateDelete (CRUD) operations using the Django Rest Framework.

In part two of this blog, we will go over how to use Django Rest Framework GenericAPIView which will make the process even easier.

Happy coding.