This article is the second part of a series on building APIs using Django – if you didn’t get a chance to check out the first part you can find it here. For this part we’re going to create the same Blog API that we made in the last article. However, this time we’re going to use a different program, so instead of basic APIView we will be working with GenericAPIView.
You may be wondering why we would use GenericAPIView when we have already proven that traditional APIView can deliver the kind of app we are looking for. The answer is that the new class extends REST class framework APIView by including some of the most commonly used functions for standard list and detail views. Let’s get into it so that you can see what I am talking about.
We begin by extending:
ListModelMixin along with GenericAPIView
The two commands provide different functionality. First, GenericAPIView allows for all of the basic features, and ListModelMixin provides the .list() function. Including Mixins allows for the actions of the basic view behavior. We also need to bind get method to list action, otherwise .list() won’t function properly.
Inserting this code lets us return a complete list of all of the articles included in the blog database, but only if there are two specific attributes included.
- queryset
This is a specified queryset of all objects that should be included in the given view. For our purposes we would like to return all of the articles. If we wanted to select for a different search criteria, we could customize by overriding get_queryset with some other command that is more specific.
- serializer_class
This attribute is used for two purposes. First it will validate and deserialize input and then it will serialize the output. We will be using the command ArticleSerializer that we created earlier.
When using the serializer though we will be including a lot of redundant information also included in the Article model. It would be ideal if we could limit this repetition and have a more concise code.
ModelSerializer
We should replace our existing serializer with a model serializer like this:
There are a few components that we get automatically by using a ModelSerializer.
Included for free are both create and update methods. There is also an auto populate feature of a set of default validators.
Don’t worry, even using the new ModelSerializer you will still be able to view the list of articles when you access the API endpoint.
Because we’re still building an app with the CRUD framework in mind, we want to give users the ability to create an article. We will use CreateModelMixin, another Mixin, to provide this function.
Use the following code to update your views.
Because one component every article has in common is that they were all created by an author, we will be using the author_id in the post request as a validation that the author exists on the platform. There are ways to code the API so that the author_id is automatically updated as the logged in user; but I’ll leave that for you to figure out on your own if you want a challenge.
You should now have the ability to send a POST request to http://127.0.0.1:8000/api/articles/ and create a new article.
Have you taken notice of how many lines of code we have already reduced from our API as compared to the first article?
It really bothers me that we even have to code for get and post methods, given that the purpose of these is simply to call other methods without any processing. There are in fact some GenericAPIViews to help with this problem, which is great because this is in fact a blog post about GenericAPIViews.
It turns out that CreateModelMixin, that we were using earlier, extends into CreateAPIView which has a more convenient post method. That means that we simply need to extend CreateAPIView and we can eliminate all the code required to include the post method ourselves. The same goes for all the extra code associated with including the get method in our API. By just extending ListAPIView, we can eliminate all the manual coding required to achieve the get method.
Update your code to this latest version:
At this point, your API should still be working properly.
Another code saver we can use is to combine creation of a new article and listing of an article into a special GenericView by using ListCreateAPIView. Go ahead and update your code to reflect these improvements.
Another feature we would like to include for our clients is the ability for a user to update their own articles. The first step in this process is providing a function for users to retrieve the article they would like to change. The RetrieveAPIView has been provided by DRF for exactly this purpose. For a single article retrieval, we will extend a new class using RetrieveAPIView as you can see below.
Did you happen to notice that we only added a single class but as a result an entire feature was completed?
That is the amazing part of GenericViews.
We need to make sure that we are continually updating our URLs. Add the following to your urls.py.
As I mentioned earlier, the RetrieveAPIView only allows you to see one article at a time using the article id. For the purposes of updating an article, we will use GenericView, and RetrieveUpdateAPIView should work just great for this task. This command allows us to not only get a single article but at the same time we can also update that article. To make things even more simple, the DRF browsable API already pre-populates these fields.
We have now covered three of our four purposes (and one extra): create, list, retrieve and update.
If you’ve been following along through this process I’m sure you can guess what is next; deletion of articles by users. You can also probably guess, correctly I might add, that we will be using a DRF generic class to perform this function. The RetrieveUpdateDestroyAPIView is the command we can use, and as you can see it is pretty self explanatory. Once we add this class to inherit from, we will have the ability to retrieve content for update and deletion.
As you can see, I was telling the truth – using GenericAPIViews dramatically reduces the amount of code required in order to perform our goal CRUD operations. Believe it or not, with viewsets we can reduce the amount of code we need to write even more. Stay tuned for part 3 of this series to see how.
Happy coding!
If you found Esir’s blog useful, check out our other blog posts for more essential insights!