Creating Python APIs - The Django REST framework. Building a Reddit clone - Upvoting Posts.[6/n]
Now that we've added the functionality to create posts via the API, we will now add the ability to upvote the posts.
So, if we're going to have an API to create a vote, first we need to have a serializer for that vote. Just like we created for the Post.
Go to serializers.py and enter the code as following :
Also remember to import Vote from models using the command
from .models import Post, Vote
Now, lets move over to our urls.py to see how someone is going to be able to vote for a particular post.
We need the following:
The is what the id of the posts would be. For example: if it is the 1st post then it would be 1, the url would be
api/posts/1/vote Since we have multiple posts we can't just define it as 1 in the program.
The view VoteCreate is what we will create next so let's go to the views.py file.
Also don't forget to import Vote from models and VoteSerializer from serializer using the command:
from .models import Post, Vote from .serializers import PostSerializer, VoteSerializer
So if you now try to upvote the 1st post using the url
http://localhost:8000/api/posts/1/vote You should see the following:
But if you click on post to register the post then we get the following error:
We get this error because it has to know what user it has to be able to save this for. So we would need to do the same as we did with Post (the function perform_create)
After we add that and try to reload the page again and try to vote, this is what we get:
Voilà, we can now vote!
However, there is a catch!
If you click post multiple times it takes those as valid votes. But we have to restrict that. We can't have multiple votes from a single user.
So we need to check if the user has already voted for a post and we can do that by using the get_queryset function that we created.
We just need to add the following condition in the perform create function:
if self.get_queryset().exists(): raise ValidationError('You have already upvoted this')
Also don't forget to import the Validation Error using
from rest_framework.exceptions import ValidationError
If you refresh the webpage and try to vote again, you should see the following:
Congratulations! this was a big step towards creating our API, In the next article we will create a new user and check if he can upvote the post. So far, we've been using the superuser that we created at the beginning to test our API.