Creating Python APIs - The Django REST framework. Building a Reddit clone - Deleting Votes.[8/n]
2 min read
Now that we have enabled the voting functionality, let's say that someone voted for a post they didn't want to vote for. Or for whatever reason they want to take their vote back.
You can create a completely different class based view that uses DestroyAPIView But there is a much simpler way to do that. We can use Mixin to add a function that will implement the delete functionality for us.
So we start by importing Mixins.
from rest_framework import generics,permissions, mixins
Add mixins.DestroyModelMixin in
class VoteCreate(generics.CreateAPIView, mixins.DestroyModelMixin):
then create a new delete method, follow the code below with its explanation in inline comments.
Note we use Response() object and status so don't forget to import that using the command. You can import status on the same line as mixins as they are both a part of the rest_framework.
from rest_framework.response import Response
from rest_framework import generics,permissions, mixins, status
So now if you refresh your web page you should see something like this:
You got a nifty button to delete the vote!
When you click on it, it asks if you want to delete the vote.
When you click yes, It deletes your vote, and if you try to delete the vote again it says "You did not vote for this post yet". Just as we programmed it to say.
Now just because you voted for a post once, and deleted the vote does not mean you would not be able to vote for the same post again.
If you vote on a post again it will give a HTTP 201 Created status and also display the vote id.
Let's see if the code breaks if you try to vote again for the same post.
No! it doesn't break. It's working as expected.
But if you go to the full api list you can't see the total number of votes each post has got. Let's fix that!
Add the following code:
votes = serializers.SerializerMethodField() in PostSerializer class.
Make sure you add
votes in the fields of Meta class and create function get_votes
def get_votes(self, post): return Vote.objects.filter(post=post).count()
After you've done this, if you refresh the page you should see a new field called 'votes' with the total votes.
If you want to make sure it's working you can try to create a new user, logging in as that user and voting on a post.