0

I'm new at Ajax and Django. I have an Ajax like button that adds "likes" to my database. Besides the button, my template also displays the total number of likes. The button works but I can't figure out how to update the "like-count" div because calling {{ post.likes.count }} displays the old result. I'm guessing that's due to caching? To get around this I declared a like_count variable in my view and then add +=1 when liked.

How do I make {{ like_count }} work in my template? Using

return render(request, 'app/blog.html', {'like_count': like_count})

sends me to blank page instead of updating the div.

View:

@login_required
def like(request):
    if request.is_ajax():
        user = request.user
        post_id = request.POST.get('post', None)
        content = ContentType.objects.get_for_model(Post)
        like_count = Like.objects.filter(content_type=content, object_id=post_id).count()

        if Like.objects.filter(user=user, content_type=content, object_id=post_id).exists():
            # remove like
            Like.objects.filter(user=user, content_type=content, object_id=post_id).delete()
            like_count -=1

        else:
            # add a new like
            Like.objects.create(user=user, content_type=content, object_id=post_id)
            like_count +=1

    return HttpResponse()
    return render(request, 'app/blog.html', {'like_count': like_count}) 

Template:

<div id="like-count">Like {{ post.likes.count }}</div>
<form method="post" action="{% url 'like' %}" id="like-form">
         {% csrf_token %}
         <input type="hidden" id="post_id" name="post" class="hidden_id" value="{{ post.pk }}" />
  <input type="hidden" id="user_id" name="user" class="hidden_id" value="{{ user.pk }}" />
  <button class="btn">Like</button>
         </form>

<script type="text/javascript">
    var frm{{ post.id }} = $('#like-form');
    frm{{ like.id }}.submit(function (ev) {
        $.ajax({
            type: frm{{ post.id }}.attr('method'),
            url: frm{{ post.id }}.attr('action'),
            data: frm{{ post.id }}.serialize(),
            success: function (data) {
                document.getElementById("like-count").innerHTML = {{ like_count }};
            }
        });

        ev.preventDefault();
    });
</script>
Dakine
  • 198
  • 7
  • When are you seeing the same like count... after a click or even with a page refresh? – SpaceSteak Aug 05 '15 at 11:28
  • After a click. It does work after a page refresh. – Dakine Aug 05 '15 at 11:33
  • What do you see in the debug console after a click? Right now you're not updating {{ like_count }} in your script after a click, so the old value is just always there. Also, `return HttpResponse() return render(request, 'app/blog.html', {'like_count': like_count})` is only returning a blank HttpResponse(). If you want to dynamically get the new Like count, you'll need to return some JSON (which you are in the second return...) and parse that on the client. ` {{ like_count }}` is giving you the same number because it's not dynamic (it's not changing at all right now). – SpaceSteak Aug 05 '15 at 11:41
  • http://stackoverflow.com/questions/3302702/jquery-return-value-using-ajax-result-on-success this might be helpful. In simpler terms, you need to change {{ like_count }} to use the returned string or json and update the element... if it was with json then you could just `document.getElementById("like-count").innerHTML = response.id` – SpaceSteak Aug 05 '15 at 11:46
  • Thanks for your help. The console just says: ``"POST /like/ HTTP/1.1" 200 0`` I thought the problem was in the return but why is it not sending the info to the div? I don't properly understand how these returns work. – Dakine Aug 05 '15 at 11:52

1 Answers1

0

assuming Django 1.7+

def like(request):
    if request.is_ajax():
      ... make sure that this is the return that gets used
    return JsonResponse({'like_count':someVar})

on client.. something like:

  $.ajax({
            ...
            success: function(response) {
                document.getElementById('like-count').innerHTML = response['like_count'];
            }
        })
SpaceSteak
  • 224
  • 2
  • 15