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
相关产品推荐
相关产品推荐

