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

Django模型字段更新问题:点赞/踩赞按钮均触发双计数

解决Django中点赞/踩赞计数同时增加的问题

嘿,我来帮你搞定这个问题!你遇到的核心情况是:不管点不点链接,页面加载时Like和Dislike的计数就已经自动涨了,这才导致每次操作两个数值都会同步增加。下面我一步步给你拆解原因和解决方案:

问题根源

你在模板里写了{{ object.like_this_movie }}和{{ object.dislike_this_movie }},在Django模板中,这种写法会直接调用模型的方法(因为方法没有参数)。也就是说,当页面渲染的那一刻,这两个方法就已经执行了——不管你点没点击链接,Like和Dislike的数值已经各加1了。点击链接只是跳转到方法返回的URL,但计数早就提前更新过了。

正确的解决方案

我们需要把点赞/踩赞的逻辑从模型移到视图中,通过URL映射来处理点击请求,这样只有当用户主动点击链接时才会触发计数更新。

1. 修改模型(models.py)

去掉模型里的like_this_movie和dislike_this_movie方法,同时给Like/Dislike字段加上默认值(避免新建电影时出现空值错误):

from django.db import models
from django.urls import reverse

class Movies(models.Model):
    Director=models.CharField(max_length=30)
    Cast_I=models.CharField(max_length=30)
    Cast_II=models.CharField(max_length=30)
    Name=models.TextField()
    ReleaseYear=models.IntegerField()
    ImdbRating=models.CharField(max_length=2)
    Genre=models.TextField(null=True)
    Language=models.CharField(max_length=20,null=True)
    Like=models.IntegerField(default=0)  # 添加默认值0
    Dislike=models.IntegerField(default=0)  # 添加默认值0

    # 可选:添加get_absolute_url,方便跳转回详情页
    def get_absolute_url(self):
        return reverse('detail', kwargs={'pk': self.pk})

2. 配置URL(urls.py)

新增两个URL,分别对应点赞和踩赞的视图:

from django.urls import path
from .views import MovieDetailView, like_movie, dislike_movie

urlpatterns = [
    path('movie/<int:pk>/', MovieDetailView.as_view(), name='detail'),
    path('movie/<int:pk>/like/', like_movie, name='like_movie'),
    path('movie/<int:pk>/dislike/', dislike_movie, name='dislike_movie'),
]

3. 编写处理逻辑的视图(views.py)

创建两个视图函数,专门处理点赞和踩赞的请求:

from django.shortcuts import get_object_or_404, redirect
from .models import Movies
from django.views.generic import DetailView

class MovieDetailView(DetailView):
    template_name='movie/detail.html'
    queryset=Movies.objects.all()
    context_object_name = 'object'  # 保持模板中变量名一致

def like_movie(request, pk):
    # 获取对应的电影对象,不存在则返回404
    movie = get_object_or_404(Movies, pk=pk)
    movie.Like += 1
    movie.save()
    # 更新后跳回电影详情页
    return redirect('detail', pk=pk)

def dislike_movie(request, pk):
    movie = get_object_or_404(Movies, pk=pk)
    movie.Dislike += 1
    movie.save()
    return redirect('detail', pk=pk)

4. 修改模板文件

把原来的链接改成指向我们刚配置的URL,同时可以显示当前的计数:

{% block content %}
<p>
<a href="{% url 'like_movie' object.pk %}">Like ({{ object.Like }})</a>
<a href="{% url 'dislike_movie' object.pk %}">Dislike ({{ object.Dislike }})</a>
</p>
{% endblock %}

额外提示

  • 如果你想防止用户重复点赞/踩赞,可以考虑添加用户和电影的关联记录(比如用ManyToManyField),或者用session/cookie来限制同一用户的操作。
  • 生产环境中,建议用F()表达式来更新计数,避免并发问题:比如movie.Like = F('Like') + 1,这样可以在数据库层面原子更新,防止多用户同时操作时计数出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 18:02:54