为什么我的Django,jQuery,Ajax喜欢按钮喜欢所有帖子?

时间:2020-04-29 23:52:42

标签: jquery django ajax django-templates

我正在尝试在Django ListView中制作类似于社交媒体供稿的Twitter,并从 Django 3 By Example 一书中添加了一个类似于Ajax的按钮。 like功能可以在DetailView中完美运行,但是我无法在ListView中使其正常工作。在DetailView中单击“喜欢”按钮时,它喜欢页面上的所有帖子,并显示“ 1个喜欢”,然后显示“ 11110个喜欢”,然后从该位置呈指数上升。喜欢/不喜欢的切换是正确的,但不会使计数减少1;反之亦然。它一直在上升。请帮忙!

Models.py:

class Post(models.Model):
    content = models.TextField(max_length=150, blank=True)
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    image = models.ImageField(storage=PrivateMediaStorage(), upload_to = pics_path, blank=True, null=True)
    vid = models.FileField(storage=PrivateMediaStorage(), upload_to = vids_path, blank=True, null=True)
    users_like = models.ManyToManyField(User, related_name='posts_liked', blank=True)

Views.py:

@require_POST
def post_like(request):
    post_id = request.POST.get('id') 
    action = request.POST.get('action') 
    if post_id and action:
        try:
            post = Post.objects.get(id=post_id) 
            if action == 'like':
                post.users_like.add(request.user) 
            else:
                post.users_like.remove(request.user) 
            return JsonResponse({'status':'ok'})
        except: 
            pass
    return JsonResponse({'status':'ko'})

模板aka post_list.html:

{% with total_likes=post.users_like.count users_like=post.users_like.all %}
    <div class="post-info"> 
        <div>
            <span class="count">
            <span class="total">{{ total_likes }}</span>
            like{{ total_likes|pluralize }}
            </span>
            <a href="#" data-id="{{ post.id }}" data-action="{% if request.user in users_like %}un{% endif %}like" class="like button">
            {% if request.user not in users_like %} 
            Like
            {% else %}
            Unlike
            {% endif %}
            </a>
        </div>
    </div>
{% endwith %}

jQuery:

    var csrftoken = Cookies.get('csrftoken'); 
    function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); 
    }
    $.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) { 
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }   
    }
});
$(document).ready(function(){
    $('a.like').click(function(e){
        e.preventDefault();
            $.post('{% url "like" %}',
                {
                    id: $(this).data('id'), 
                    action: $(this).data('action')
                },
                function(data){
                    if (data['status'] == 'ok') 
                    {
                    var previous_action = $('a.like').data('action');
                    // toggle data-action
                    $('a.like').data('action', previous_action == 'like' ? 'unlike' : 'like');
                    // toggle link text
                    $('a.like').text(previous_action == 'like' ? 'Unlike' : 'Like');
                    // update total likes
                    var previous_likes = parseInt($('span.count .total').text()); 
                    $('span.count .total').text(previous_action == 'like' ? previous_likes + 1 : previous_likes - 1);
                } 
            }
        ); 
    });
});

1 个答案:

答案 0 :(得分:0)

好像您正在选择DOM上的所有a.like元素一样,span.count.total

选择时应该更加具体,最好使用id。例如在<a>中:

<a href="#" id="{{ post.id }}" data-id="{{ post.id }}" data-action="{% if request.user in users_like %}un{% endif %}like" class="like button">

然后在jQuery中使用

$(document).ready(function(){
    $('a.like').click(function(e){
        e.preventDefault();
            var id = $(this).data('id');
            var action = $(this).data('action');
            $.post('{% url "like" %}',
                {
                    id: id, 
                    action: action
                },
                function(data){
                    if (data['status'] == 'ok') 
                    {
                    var previous_action = $('#' + id').data('action');
                    // toggle data-action
                    $('#' + id).data('action', previous_action == 'like' ? 'unlike' : 'like');
                    // toggle link text
                    $('#' + id).text(previous_action == 'like' ? 'Unlike' : 'Like');
                    // update total likes
                    var previous_likes = parseInt($('span.count .total').text()); 
                    $('#' + id + '_total').text(previous_action == 'like' ? previous_likes + 1 : previous_likes - 1);
                } 
            }
        ); 
    });
});

与span元素相同。请记住,您应该为每个元素使用 unique id,因此也许可以附加诸如id="{{ post.id }}_like"id="{{ post.id }}_count"id="{{ post.id }}_total"之类的后缀来区分。

相关问题