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

Django用户唯一点赞按钮异常:重复点击致重复计数问题

问题分析与解决方案

核心问题定位

你的点赞重复计数问题根源在TweetLike模型的错误字段设置,导致数据库层面的唯一性约束逻辑混乱:

  • liker字段设置了unique=True,这会强制一个用户只能创建一条点赞记录,意味着用户只能给某一条推文点赞,完全违背多推文点赞的需求。
  • like_count字段设置了unique=True,该字段全局唯一的约束毫无意义,还会引发数据库报错。
  • 虽然你设置了unique_together = ('tweet', 'liker'),但liker的unique=True会覆盖联合约束的作用,导致逻辑冲突。

修复步骤

1. 修正TweetLike模型

修改models.py中的TweetLike类,移除错误的unique设置,保留联合唯一约束:

# Tweet Like
# --------------
class TweetLike(models.Model):
    creation_date = models.DateField(default=timezone.now)
    id = models.AutoField(primary_key=True)
    tweet = models.ForeignKey(
        Tweet,
        on_delete=models.CASCADE,
        blank=True,
        null=True
    )
    liker = models.ForeignKey(
        BasicUserProfile,
        on_delete=models.CASCADE,
        blank=True,
        null=True
        # 移除 unique=True 约束
    )
    # 移除 like_count 字段,无需单独存储该值

    class Meta:
        unique_together = ('tweet', 'liker')  # 保留该约束,确保单用户对单推文仅能创建一条点赞记录

    def __str__(self):
        return f"Like id: {self.id}"

2. 优化视图逻辑

视图中判断用户是否已点赞时,使用exists()方法更高效清晰,同时确保计数逻辑准确:

if request.POST.get("single_tweet_like_submit_btn"):
    try:
        print(f"Request by user: {current_basic_user_profile.user.username} for tweet ID: {current_tweet.id}")

        # 改用exists()判断是否已点赞,性能更优
        has_liked = TweetLike.objects.filter(tweet=current_tweet, liker=current_basic_user_profile).exists()
        
        if has_liked:
            print(f"User {current_basic_user_profile.user.username} has already liked tweet {current_tweet.id}, unliking it.")
            # 删除该用户对这条推文的点赞(联合唯一约束确保仅存在一条记录)
            TweetLike.objects.filter(tweet=current_tweet, liker=current_basic_user_profile).delete()
            current_tweet.tweet_like_amount = max(0, current_tweet.tweet_like_amount - 1)
        else:
            print(f"User {current_basic_user_profile.user.username} has not liked tweet {current_tweet.id}, liking it.")
            new_like = TweetLike(tweet=current_tweet, liker=current_basic_user_profile)
            new_like.save()
            current_tweet.tweet_like_amount += 1
            
            new_notification = NotificationLike(
                notified=current_tweet.user,
                notifier=current_basic_user_profile,
                tweet=current_tweet,
            )
            new_notification.save()
        
        current_tweet.save()
        print(f"Tweet {current_tweet.id} now has {current_tweet.tweet_like_amount} likes.")
        
    except Exception as e:
        print(f"An error occurred: {e}")
    
    return HttpResponseRedirect(f"/tweet/{current_tweet.id}/")

3. 可选优化:避免手动维护点赞数

手动维护tweet_like_amount容易出现计数不一致的情况,建议通过关联查询实时获取点赞数,在Tweet模型中添加属性:

class Tweet(models.Model):
    # 你的其他字段...
    tweet_like_amount = models.IntegerField(default=0)  # 可保留,但推荐用下面的属性替代

    @property
    def real_like_count(self):
        return self.tweetlike_set.count()

在模板中使用{{ tweet.real_like_count }}即可获取准确的点赞数,无需手动维护计数。

最后操作

修改模型后,执行数据库迁移命令:

python manage.py makemigrations
python manage.py migrate

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 09:10:55