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 :

image.png

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:

image.png

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.

image.png

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:

image.png

But if you click on post to register the post then we get the following error:

image.png

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)

image.png

After we add that and try to reload the page again and try to vote, this is what we get:

image.png

Voilà, we can now vote!

However, there is a catch!

image.png

image.png

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')

image.png

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:

image.png

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.