Не удается удалить django-vote
Я работаю над небольшим университетским проектом. И я хочу добавить голосование в мое приложение.
Я решил использовать для этого django-vote.
Вот документация: https://pypi.org/project/django-vote/
Голосование работает нормально.
Проблема в том, что когда я хочу удалить существующий голос, это не работает.
Я видел эту тему Django model: delete() not triggered
но я не понял его.
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)
Моя модель:
class Book(VoteModel, models.Model):
....
Либо используйте:
book.votes.filter(user_id=request.user.id).delete()
Or:
Vote.objects.filter(user_id=request.user.id).delete()
Вы используете неправильный синтаксис Django, метод delete()
не принимает никаких параметров, down()
не является встроенным методом в менеджер объектов Django по умолчанию, и exists()
должен использоваться с фильтром, например:
book.votes.filter(user_id=request.user.id).exists()
Я не мог понять, почему в моем проекте не работает delete в библиотеке Django-vote. Я понял, что не смогу заставить ее работать. Поэтому я решил написать свое собственное решение для голосования. На всякий случай, если кому-то это понадобится. Вот оно
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)
Я использовал редирект, чтобы не голосовать дважды.
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('/')