Django - система голосования

Я столкнулся с простой проблемой. Я хочу создать систему голосования. У меня есть простой код, который не работает должным образом. Когда я нажимаю кнопку UP, она добавляет +1, когда я нажимаю UP снова, она убирает -1. То же самое с кнопкой DOWN. Проблема в том, что когда я нажимаю между кнопками UP и DOWN. Значение увеличивается или уменьшается (бесконечно) - это зависит от того, какая кнопка была первой.

def vote_comment(request):
comment = get_object_or_404(CommentsCode, id=request.POST.get('id'))
is_voted = comment.is_voted.filter(id=request.user.id).exists()
up = request.POST['name'] == "UP"
down = request.POST['name'] == "DOWN"

if up:
    if is_voted:
        comment.is_voted.remove(request.user)
        comment.vote -= 1
        comment.save()
    else:
        comment.is_voted.add(request.user)
        comment.vote += 1
        comment.save()
elif down:
    if is_voted:
        comment.is_voted.remove(request.user)
        comment.vote += 1
        comment.save()
    else:
        comment.is_voted.add(request.user)
        comment.vote -= 1
        comment.save()

Когда вы нажимаете UP в первый раз, is_voted становится ложным, и возникает условие else, и голос увеличивается на 1. Теперь в следующий раз is_voted будет истинным, и таким образом оператор if будет истинным, и голос уменьшится на 1. Возможно, это сработает (у меня не было возможности проверить это):

def vote_comment(request):
    comment = get_object_or_404(CommentsCode, id=request.POST.get('id'))
    is_voted = comment.is_voted.filter(id=request.user.id).exists()
    up = request.POST['name'] == "UP"
    down = request.POST['name'] == "DOWN"

    if not is_voted:
        comment.is_voted.add(request.user)
        if down:
            comment.vote -= 1
        elif up:
            comment.vote += 1
        comment.save()

    # Or might even be easier like this:

    #if not is_voted:
    #    comment.is_voted.add(request.user)
    #    comment.vote = comment.vote + 1 if up else comment.vote - 1
        

EDIT

На основе вашего шаблона я вижу еще одну ошибку. Атрибут name - это то, что request.POST отправит в качестве ключа, value - это значение, которое будет отправлено. Таким образом, нет никакого request.POST['name'], поскольку у вас нет ничего, что говорило бы name='name'. Попробуйте сделать следующее:

<form action="{% url 'xvote_comment' %}" method="post">
    {% csrf_token %}
    <div id="vov-{{q.pk}}">
        {{q.vote}}
        <button type="submit" id="like" name="vote" value="UP"
            class="btn btn-danger">!UP</button>
        <button type="submit" id="like" name="vote" value="DOWN"
            class="btn btn-primary">DOWN</button>
    </div>
</form>

Тогда, по вашему мнению:

def vote_comment(request):
    comment = get_object_or_404(CommentsCode, id=request.POST.get('id'))
    print(request.POST) # Check to see what is actually being sent
    is_voted = comment.is_voted.filter(id=request.user.id).exists()
    up = request.POST['vote'] == "UP"
    down = request.POST['vote'] == "DOWN"

    if not is_voted:
        comment.is_voted.add(request.user)
        if down:
            comment.vote -= 1
        elif up:
            comment.vote += 1
        comment.save()

    # Or might even be easier like this:

    #if not is_voted:
    #    comment.is_voted.add(request.user)
    #    comment.vote = comment.vote + 1 if up else comment.vote - 1
Вернуться на верх