Creating Python APIs - The Django REST framework. Building a Reddit clone - Deleting Votes.[8/n]

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.

image.png

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:

image.png

You got a nifty button to delete the vote!

When you click on it, it asks if you want to delete the vote.

image.png

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.

image.png

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.

image.png

Let's see if the code breaks if you try to vote again for the same post.

image.png

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:

image.png

Add 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.

image.png

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.