I'm stuck with a simple problem. I want to create a voting system. I have a simple code that doesn't work properly. When I click UP it adds +1, when I click UP again, it removes -1. Same with the DOWN button. The problem is that when I click between the UP and DOWN buttons. The value increases or decreases (indefinitely) - it depends with the click of the button first.
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()
template.html
<form action="{% url 'xvote_comment' %}" method="post">
{% csrf_token %}
<div id="vov-{{q.pk}}">
{{q.vote}}
<button type="submit" id="like" name="UP" value="{{ q.pk }}"
class="btn btn-danger">!UP</button>
<button type="submit" id="like" name="DOWN" value="{{ q.pk }}"
class="btn btn-primary">DOWN</button>
</div>
</form>
models.py
class CommentsCode(models.Model):
cpost = models.ForeignKey(CodePost, on_delete=models.CASCADE, null=True, blank=True)
cauthor = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
body = models.TextField()
vote = models.IntegerField(default=0)
is_voted = models.ManyToManyField(User, related_name='is_voted', blank=True)
is_approved = models.BooleanField(default=True)
js in template
<script type="text/javascript">
$(document).ready(function (event) {
$(document).on('click', '#like', function (event) {
event.preventDefault();
var pk = $(this).attr('value');
var name = $(this).attr('name');
$.ajax({
type: 'POST',
url: '{% url "xvote_comment" %}',
data: {
'id': pk,
'name': name,
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function (response) {
$('#vov-' + pk).load(" #vov-" + pk);
console.log(response)
},
error: function (rs, e) {
console.log(rs.responseText);
},
});
});
});
</script>
EDIT
I finally have the code written, maybe not optimal, but I'm just learning. Thank you for all your help
def vote_comment(request):
comment = get_object_or_404(CommentsCode, id=request.POST.get('id'))
is_voted_positive = comment.is_voted_p.filter(id=request.user.id).exists()
is_voted_negative = comment.is_voted_n.filter(id=request.user.id).exists()
up = request.POST['name'] == "UP"
down = request.POST['name'] == "DOWN"
if up and is_voted_positive:
comment.is_voted_p.add(request.user)
comment.is_voted_n.remove(request.user)
elif up and not is_voted_positive:
comment.is_voted_p.add(request.user)
if is_voted_negative:
comment.is_voted_p.remove(request.user)
comment.is_voted_n.remove(request.user)
comment.vote += 1
comment.save()
elif up and is_voted_negative:
comment.is_voted_n.remove(request.user)
comment.is_voted_p.add(request.user)
comment.vote += 1
comment.save()
elif down and is_voted_positive:
comment.is_voted_n.add(request.user)
if is_voted_positive:
comment.is_voted_p.remove(request.user)
comment.is_voted_n.remove(request.user)
comment.vote -= 1
comment.save()
elif down and is_voted_negative:
pass
elif down and not is_voted_negative:
comment.is_voted_n.add(request.user)
if is_voted_positive:
comment.is_voted_p.remove(request.user)
comment.is_voted_n.remove(request.user)
comment.vote -= 1
comment.save()
and it's look: