Django Like Button with AJAX Request

I'm trying to create an AJAX request in Django to update a Like Button.

I'm getting an Error from the AJAX call. Not sure how to troubleshoot it.

Can anybody point me in the right direction?

enter image description here

.script

$(".vote-form").submit(function(e) {
          e.preventDefault();
          let poopfact_id = $(this).attr("id");
          const voteCount = $(`.voteCount${poopfact_id}`).text();
          let url = $(this).attr('action');
  $.ajax({
            type: 'POST',
            url: url,
            data: {
              'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val(),
              'poopfact_id': poopfact_id,
            },
            
            success: function(response) {
              document.getElementById("vote_count").innerHtml = response['total_votes']
              console.log('success', response)
              
            },
            error: function(response) {
              console.log('error', response),
            },
          });

.views

def vote(request, poopfact_id):
    user = request.user
    post = get_object_or_404(PoopFact, id=poopfact_id)
    if request.method=="POST":
        if user.is_authenticated:
            if "upvote" in request.POST:
                if user in post.upvote.all():
                    post.upvote.remove(request.user)
                    total_votes = post.upvote.count() - post.downvote.count()
                    data = {"total_votes": total_votes}
                    return  JsonResponse(data, safe=False)
                else:
                    post.upvote.add(request.user)
                    post.downvote.remove(request.user)
                    total_votes = post.upvote.count() - post.downvote.count()
                    data = {"total_votes": total_votes}
                    return  JsonResponse(data, safe=False)
        else:
            return HttpResponseRedirect(reverse('user_login'))

.html

<form action="{% url 'vote' poopfact.id %}" style="display: inline-block" method="POST" class="vote-form" id="{{poopfact.id}}">
  ... 
  <div class="voteCount{{poopfact.id}}" id="vote_count">{{   poopfact.total_votes }}</div>
  <button type="submit" name="upvote" class="btn btn-primary"><i   class="fa-solid fa-up-long"></i></i></button>
  ...

Here is an alternative solution:

template body:

{% for fact in poopfacts %}
    <div id="{{ fact.id }}">{{ fact.total_votes}}</div>
    <button value="" onclick="addVote('{{ fact.id }}', 1)">+</button>
    <button value="" onclick="addVote('{{ fact.id }}', -1)">-</button>
    <hr>
{% endfor %}

.script:

<script>
    function addVote(id, vote) {
        let url = "{% url 'core:poop-facts-vote' %}";
        $.ajax({
            type: 'POST',
            url: url,
            data: {
            csrfmiddlewaretoken: '{{ csrf_token }}',
            'id': id,
            'vote': vote,
            },
            success: function(response) {
                total_votes = response['votes'];
                poopfact_id = response['id'];
                e = document.getElementById(poopfact_id)
                e.innerHTML = total_votes;
                console.log('success', response);
            },
            error: function(response) {
                console.log('success', response);
            },
        });
    }
</script>

views.py:

from django.http import JsonResponse
from core.models import PoopFact
from django.shortcuts import get_object_or_404

def poop_facts_vote(request):
    id = request.POST.get('id')
    vote = int(request.POST.get('vote'))

    if request.user.is_authenticated:
        poopfact = get_object_or_404(PoopFact, id=id)
        poopfact.total_votes += vote
        poopfact.save()
        poopfact.refresh_from_db()
        return JsonResponse({'votes': poopfact.total_votes, 'id': poopfact.id})

def poop_facts(request):
    poopfacts = PoopFact.objects.all()
    return render(request, 'poop_facts.html', {'poopfacts': poopfacts})

models.py

class PoopFact(models.Model):
    total_votes = models.IntegerField()

Adapting to you upvote / downvote model:

def poop_facts_vote(request):
    id = request.POST.get('id')
    vote = int(request.POST.get('vote'))

    if request.user.is_authenticated:
        poopfact = get_object_or_404(PoopFact, id=id)
        if vote > 0:
            # upvote
            ...
        else:
            # downvote
            ...

        return JsonResponse({'votes': poopfact.total_votes, 'id': poopfact.id})
Back to Top