Can't delete django-vote
I am working on a small university project. And I want to add voting to my app.
I've decided to use django-vote for it.
Here is the documentation: https://pypi.org/project/django-vote/
Upvoting works fine.
The problem is whenever I want to delete existing vote it doesn't work.
I saw this thread Django model: delete() not triggered
but I didn't understand it.
from vote.models import UP, DOWN
...
book = get_object_or_404(Book, id=pk)
...
if 'upvote' in request.POST:
print("I clicked upvote")
if book.votes.exists(request.user.id):
print("upvote exists")
book.votes.delete(request.user.id)
else:
book.votes.up(request.user.id)
if 'downvote' in request.POST:
print("I clicked downvote")
if book.votes.exists(request.user.id, action=DOWN):
print("downvote exists")
book.votes.delete(request.user.id)
else:
book.votes.down(request.user.id)
My model:
class Book(VoteModel, models.Model):
....
Either use:
book.votes.filter(user_id=request.user.id).delete()
Or:
Vote.objects.filter(user_id=request.user.id).delete()
You are not using correct Django syntax, the delete()
method does not takes any params, down()
is not built-in method in Django default objects manager, and exists()
should be used with filter, for e.g.:
book.votes.filter(user_id=request.user.id).exists()
I couldn't figure out why delete is not working in Django-vote library in my project. I've realized that I won't be able to make it work. So I've decided to write my own custom solution for voting. Just in case if someone needs it. Here it is
votes_types=(
('downvote', 'downvote'),
('no vote', 'no vote'),
('upvote', 'upvote')
)
class Book(models.Model):
....
num_votes_up = models.IntegerField("number of upvotes", blank=True, default=0)
num_votes_down = models.IntegerField("number of upvotes", blank=True, default=0)
class Votes(models.Model):
userid = models.ForeignKey(User,on_delete=models.CASCADE)
book_id = models.ForeignKey(Book,on_delete=models.CASCADE)
vote_type = models.TextField("Vote type", blank=True, default='no vote', choices=votes_types)
I used redirect to avoid voting twice.
def learnmore(request,pk):
book = get_object_or_404(Book, id=pk)
....
upvotes = Votes.objects.filter(userid=request.user, book_id=book, vote_type="upvote")
downvotes = Votes.objects.filter(userid=request.user, book_id=book, vote_type="downvote")
if 'upvote' in request.POST:
upvote = Votes.objects.filter(userid=request.user, book_id=book)
if upvote:
upvote.delete()
book.num_votes_up-=1
book.save()
messages.info(request, "upvote removed" )
return redirect('/')
else:
upvote = Votes.objects.update_or_create(userid=request.user, book_id=book, vote_type="upvote")
book.num_votes_up+=1
book.save()
messages.info(request, "upvoted" )
return redirect('/')
if 'downvote' in request.POST:
downvote = Votes.objects.filter(userid=request.user, book_id=book)
if downvote:
downvote.delete()
book.num_votes_down-=1
book.save()
messages.info(request, "downvote removed" )
return redirect('/')
else:
downvote = Votes.objects.update_or_create(userid=request.user, book_id=book, vote_type="downvote")
book.num_votes_down+=1
book.save()
messages.info(request, "downvoted" )
return redirect('/')