darkhorse
darkhorse

Reputation: 8722

Why does my like button only work on the first instance of a list in Django?

I follow Tango with Django's tutorial for adding the like button. I thought it worked, but it only seems to be working for the very first model instance in a list. You see, I have a view where all the objects in a list is displayed. My code looks like this:

views.py

def content_list(request):
    posts = Post.objects.all()
    return render(request, 'app/content_list.html', {'posts' : posts})

models.py

class Post(models.Model):
    user = models.ForeignKey(User, related_name = 'user_posts')
    title = models.CharField(max_length = 140)
    votes = models.IntegerField(default = 0)

content_list.html - the template

{% for post in posts %}
    <h1>{{post.title}}</h1>
    <p><strong id="like_count">{{post.votes}}</strong> points</p>
    {% if request.user.is_authenticated %}
        <button id="likes" data-post-id="{{post.id}}" class="btn btn-purple" type="button">
            <span>Upvote</span>
        </button>
    {% endif %}
 {% endfor %}

In views.py, I have another function which handles the post-liking:

@login_required
def like_post(request):
    post_id = None

    # Getting the id of the post from the template
    if request.method == 'GET':
        post_id = request.GET['post_id']

    likes = 0

    if post_id:
        post = Post.objects.get(id = int(post_id))
        if post:
            likes = post.votes + 1
            post.votes = likes
            post.save()

    return HttpResponse(likes)

And finally, my ajax file which does the actual work:

$('#likes').click(function(){
    var p_id;
    p_id = $(this).attr("data-post-id");
    $.get('/like_post/', {post_id: p_id}, function(data){
       $('#like_count').html(data);
       $('#likes').hide();
    });
});

My urls.py in my app folder has the following line in the url patterns:

# Liking a post
url(r'^like_post/$', views.like_post, name='like_post'),

What am I missing? The uproot button for the other posts don't hide either, which they should because of my ajax code. How can I fix this problem?

Thanks!

Upvotes: 1

Views: 334

Answers (1)

Adib Aroui
Adib Aroui

Reputation: 5067

By applying what was mentionned in comments, your server code could become:

{% for post in posts %}
    <h1>{{post.title}}</h1>
    <p><strong id="like_count">{{post.votes}}</strong> points</p>
    {% if request.user.is_authenticated %}
        <button data-post-id="{{post.id}}" class="likes btn btn-purple" type="button">
            <span>Upvote</span>
        </button>
    {% endif %}
 {% endfor %}

And the javascript part is now:

$('.likes').click(function(){
    var p_id;
    p_id = $(this).attr("data-post-id");
    $.get('/like_post/', {post_id: p_id}, function(data){
       $('#like_count').html(data);
       $(this).hide();
    });
});

Upvotes: 1

Related Questions