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

Django+Ajax点赞功能like_count数值翻倍异常求助

问题分析与解决方案

你的点赞按钮数值增减两次的核心原因是后端修改数据库数值 + 前端不等待响应直接本地修改的双重操作,再加上代码中的几处逻辑错误,导致数据更新重复。以下是具体问题和修复步骤:


核心问题点

  1. 重复数值更新:后端视图已经修改了数据库中的likes_count,但前端在Ajax请求发送后立刻手动增减数值,导致数值被修改两次。
  2. 视图响应错误:Ajax是异步请求,不需要重定向,但你的视图返回了HttpResponseRedirect,既不符合异步场景需求,也可能引发额外的页面行为。
  3. 模型与视图字段不匹配:模型定义的多对多字段是favs,但视图中使用了post.likes.all(),这会导致点赞状态判断完全失效(如果模型没有likes字段会直接报错,若为笔误则逻辑混乱)。
  4. 前端依赖旧数据:前端使用页面加载时的旧点赞数计算新值,而非后端返回的最新数据,容易出现数据不一致。

修复步骤

1. 修正视图逻辑,返回JSON数据

将视图改为返回包含最新点赞状态和点赞数的JSON,同时修复字段匹配问题:

from django.http import JsonResponse
from django.db.models import F  # 用于避免并发竞态条件

class AddLike(LoginRequiredMixin, View):
    def post(self, request, pk, *args, **kwargs):
        post = Post.objects.get(pk=pk)
        # 高效判断用户是否已点赞
        is_liked = post.favs.filter(id=request.user.id).exists()

        if not is_liked:
            post.favs.add(request.user)
            post.likes_count = F('likes_count') + 1  # 用F表达式避免并发问题
        else:
            post.favs.remove(request.user)
            post.likes_count = F('likes_count') - 1
        
        post.save()
        post.refresh_from_db()  # 刷新获取最新数值

        # 返回JSON给前端
        return JsonResponse({
            'likes_count': post.likes_count,
            'is_liked': not is_liked  # 返回当前最新的点赞状态
        })

2. 调整前端Ajax逻辑,等待响应后更新DOM

把DOM修改逻辑移到Ajax的success回调中,完全依赖后端返回的最新数据,避免本地旧值干扰:

$(document).on('submit','#like-post',function(e){
    e.preventDefault();
    var $form = $(this);
    var pkey = $form.find('input[name="pk"]').val();  // 用name选择更可靠,避免索引错误

    $.ajax({
        type:'POST',
        url:"/social/post/"+pkey+"/like",
        data:{
            csrfmiddlewaretoken:$form.find('input[name=csrfmiddlewaretoken]').val(),
        },
        success: function(response){
            // 用后端返回的最新数据更新页面
            $('#count'+pkey).text(response.likes_count);
            
            if (response.is_liked) {
                $('#no-like' + pkey).hide();
                $('#liked' + pkey).show();
            } else {
                $('#no-like' + pkey).show();
                $('#liked' + pkey).hide();
            }
        },
        error: function(){
            console.log('点赞操作失败');
        }
    });
});

3. 优化HTML(可选)

移除不需要的like-count隐藏输入,改用后端返回数据,同时修正模板中的字段引用:

<form method="POST" id="like-post">
    {% csrf_token %}
    <input type="hidden" name="next" value="{{ request.path }}">
    <input type="hidden" name="pk" value="{{ post.pk }}">

    <button style="background-color: transparent; border: none; box-shadow: none;" type="submit">
        <span id="count{{ post.pk }}">{{ post.likes_count }}</span>
        {% if request.user in post.favs.all %}
            <i id="no-like{{ post.pk }}" style="color:gray; display: none;" class="fa-solid fa-champagne-glasses"></i>
            <i id="liked{{ post.pk }}" style="color:green;" class="fa-solid fa-champagne-glasses"></i>
        {% else %}
            <i id="liked{{ post.pk }}" style="color:green; display: none;" class="fa-solid fa-champagne-glasses"></i>
            <i id="no-like{{ post.pk }}" style="color:gray;" class="fa-solid fa-champagne-glasses"></i>
        {% endif %}
    </button>
</form>

内容的提问来源于stack exchange,提问作者João Branco

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 06:54:22