You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中点赞按钮无法切换为取消点赞按钮问题排查

问题解决思路

你的问题出在两个核心点:模板变量引用错误,以及AJAX成功后没有切换按钮的DOM结构。下面是具体修复步骤:

1. 修复模板中的变量引用错误

你在模板里写的{% if post.liked_by_current_user %}是错误的——liked_by_current_user是视图单独传入上下文的变量,并不是post对象的属性,直接用变量名即可:

{% if liked_by_current_user %}
    <div class="unlike-button" data-post-id="{{ post.id }}">Dislike<span class="like-count-value" data-post-id="{{ post.id }}">{{ like_count }}</span></div>
{% else %}
    <div class="like-button" data-post-id="{{ post.id }}">Like<span class="like-count-value" data-post-id="{{ post.id }}">{{ like_count }}</span></div>
{% endif %}

2. 完善AJAX的DOM切换逻辑

原来的JS只更新了点赞数,但没有切换按钮本身,而且你写了两段重复的$(document).ready代码,会导致事件绑定两次,触发重复请求。合并代码并添加按钮切换逻辑:

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
    // 用事件委托处理动态生成的按钮(切换后按钮是新生成的,直接绑定会失效)
    $(document).on('click', '.like-button, .unlike-button', function() {
        var $btn = $(this);
        var postId = $btn.data('post-id');
        var csrfToken = '{{ csrf_token }}';
        var isLikeBtn = $btn.hasClass('like-button');
        var requestUrl = isLikeBtn ? '/like/' + postId + '/' : '/unlike/' + postId + '/';

        $.ajax({
            type: 'POST',
            headers: {'X-CSRFToken': csrfToken},
            url: requestUrl,
            success: function(res) {
                // 验证请求成功
                if ((isLikeBtn && res.liked) || (!isLikeBtn && res.unliked)) {
                    // 更新点赞数
                    $btn.find('.like-count-value').text(res.like_count);
                    // 切换按钮类型和文本
                    if (isLikeBtn) {
                        $btn.removeClass('like-button').addClass('unlike-button')
                            .html(`Dislike<span class="like-count-value" data-post-id="${postId}">${res.like_count}</span>`);
                    } else {
                        $btn.removeClass('unlike-button').addClass('like-button')
                            .html(`Like<span class="like-count-value" data-post-id="${postId}">${res.like_count}</span>`);
                    }
                }
            },
            error: function(xhr) {
                console.error(xhr.responseText);
            }
        });
    });

    // 初始化加载点赞数(确保你的/get_like_count/视图已正确实现)
    function refreshLikeCounts() {
        $('.like-count-value').each(function() {
            var $countEl = $(this);
            var postId = $countEl.data('post-id');
            $.ajax({
                type: 'GET',
                url: '/get_like_count/' + postId + '/',
                success: function(res) {
                    var count = parseInt(res.like_count);
                    if (!isNaN(count)) $countEl.text(count);
                },
                error: function(xhr) {
                    console.error(xhr.responseText);
                }
            });
        });
    }

    refreshLikeCounts();
});
</script>

3. 额外说明

  • 事件委托:因为按钮是动态替换的,直接绑定.click()只会对初始渲染的元素生效,用$(document).on()可以监听动态生成元素的点击事件。
  • 重复代码清理:原来的两段JS代码会导致事件绑定两次,合并后避免了重复请求的问题。

内容的提问来源于stack exchange,提问作者Super DReik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 11:05:56