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

Django模型无法保存AJAX请求数据:点赞计数更新失败

Django点赞计数器无法更新数据库问题解决

问题描述

我是Ajax和Django新手,代码若有混乱还请见谅。我在尝试实现基础的点赞、点踩计数器时遇到问题:尽管前端发送了请求到view.py的likePost函数,但Django模型的like_votes字段始终无法更新,数据库中的点赞值无法保存。

现有代码

模型代码(models.py)

class Post(models.Model):
    post_text = models.CharField(max_length=1000)
    pub_date = models.DateTimeField('date published')
    like_votes = models.IntegerField(default=0)
    dislike_votes = models.IntegerField(default=0)

    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

    def __str__(self):
        return self.post_text

AJAX代码(前端模板)

<script type="text/javascript">
    var likebtn = document.getElementById("likebtn");
    likebtn.addEventListener('click', buttonClikckHandler);

    var num1 = 1;
    var like = parseInt("{{post.like_votes}}");
    var new_l = like;

    function buttonClikckHandler() {
        console.log("clicked like");

        const xhr = new XMLHttpRequest();

        var new_l = like + num1 % 2;
        num1 = num1 + 1;
        document.getElementById("like").innerHTML = new_l;

        var catid;
        catid = $(this).attr("data-catid");
        $.ajax({
            type: "GET",
            url: "/likepost",
            data: {
                post_id: catid , 
                votes : new_l
            },
            success: function (data) {
                $('#like' + catid).remove();
                $('#message').text(data);
            }
        })

        console.log(new_l, num1);
    }
</script>

视图代码(views.py)

def likePost(request ):
    if request.method == 'POST':
           post_id = request.POST['post_id']
           print( post_id)
           likedpost = Post.objects.get(pk=post_id) 
           likedpost.like_votes = int(request.POST['votes'])
           likedpost.save()
           return HttpResponse("Success!") 
    else:
           return HttpResponse("Request method is not a POST")

问题分析

  1. 请求方法不匹配:前端AJAX用GET请求,但视图只处理POST请求,导致每次请求都进入else分支,未执行数据库更新逻辑。
  2. 前端计算逻辑不合理:前端自行计算点赞数并传给后端,易出现数据不一致,且未考虑并发场景下的竞争问题。
  3. 缺少CSRF令牌:Django默认拦截无CSRF令牌的POST请求,这是新手常忽略的安全机制。
  4. 数据更新逻辑有风险:视图直接用前端传来的值覆盖数据库字段,未保障数据准确性与并发安全。

修复方案

修改AJAX代码

<script type="text/javascript">
    var likebtn = document.getElementById("likebtn");
    likebtn.addEventListener('click', buttonClikckHandler);

    function buttonClikckHandler() {
        console.log("clicked like");
        const catid = this.getAttribute("data-catid");
        
        $.ajax({
            type: "POST",
            url: "/likepost",
            data: {
                post_id: catid,
                csrfmiddlewaretoken: "{{ csrf_token }}" // 添加CSRF令牌通过验证
            },
            success: function (response) {
                // 用后端返回的最新值更新页面,保障数据一致性
                document.getElementById("like").innerHTML = response.like_votes;
                $('#message').text("点赞成功!");
            },
            error: function(xhr) {
                $('#message').text("操作失败:" + xhr.responseText);
            }
        });
    }
</script>

修改视图代码

from django.db.models import F
from django.http import JsonResponse

def likePost(request):
    if request.method == 'POST':
        post_id = request.POST.get('post_id')
        if not post_id:
            return JsonResponse({'error': '缺少帖子ID参数'}, status=400)
        
        try:
            likedpost = Post.objects.get(pk=post_id)
            # 使用F表达式执行原子更新,避免并发点赞导致的数据覆盖
            likedpost.like_votes = F('like_votes') + 1
            likedpost.save()
            # 刷新对象获取最新数据库值
            likedpost.refresh_from_db()
            return JsonResponse({'like_votes': likedpost.like_votes})
        except Post.DoesNotExist:
            return JsonResponse({'error': '该帖子不存在'}, status=404)
    else:
        return JsonResponse({'error': '仅支持POST请求'}, status=405)

关键说明

  • 原子更新:F表达式让数据库直接执行like_votes +=1,避免多用户同时点赞时的数据不一致问题。
  • 数据一致性:页面点赞数完全依赖后端返回的最新值,确保前端显示与数据库状态同步。
  • CSRF安全:必须添加csrfmiddlewaretoken参数,通过Django的CSRF验证,避免请求被拦截。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 03:50:17