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

如何在Django中创建每个用户专属的本地模型字段(如评论点赞状态)

在Django中为Comment模型添加用户专属的点赞状态字段

方法一:使用数据库注解(推荐,高效)

通过Django的Exists子查询和annotate,直接在查询Comment时将当前用户的点赞状态作为字段返回,一次数据库查询即可完成,性能更优。

首先定义点赞关联模型:

# models.py
from django.db import models
from django.contrib.auth import get_user_model

User = get_user_model()

class Comment(models.Model):
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    # 其他业务字段,比如关联文章的外键等

class CommentLike(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    comment = models.ForeignKey(Comment, on_delete=models.CASCADE, related_name='likes')
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ('user', 'comment')  # 限制单用户单评论只能点赞一次

在视图中查询评论时添加注解:

# views.py
from django.db.models import Exists, OuterRef
from django.shortcuts import render
from .models import Comment, CommentLike

def comment_list(request):
    current_user = request.user
    comments = Comment.objects.all()

    if current_user.is_authenticated:
        # 用Exists子查询判断当前用户是否点赞该评论
        comments = comments.annotate(
            is_liked=Exists(
                CommentLike.objects.filter(
                    user=current_user,
                    comment=OuterRef('pk')
                )
            )
        )
    else:
        # 未登录用户默认所有评论都未点赞
        comments = comments.annotate(is_liked=models.Value(False, output_field=models.BooleanField()))

    return render(request, 'comment_list.html', {'comments': comments})

模板中直接调用字段:

<!-- comment_list.html -->
{% for comment in comments %}
    <div class="comment-item">
        <p>{{ comment.content }}</p>
        <span>{% if comment.is_liked %}已点赞{% else %}未点赞{% endif %}</span>
    </div>
{% endfor %}

方法二:批量查询后手动添加属性(适合小数据量场景)

如果不想依赖数据库注解,可以先获取所有评论,再批量查询当前用户的点赞记录,给每个Comment实例手动添加is_liked属性,避免N+1查询问题。

视图代码示例:

# views.py
from django.shortcuts import render
from .models import Comment, CommentLike

def comment_list(request):
    current_user = request.user
    comments = list(Comment.objects.all())

    if current_user.is_authenticated:
        # 一次性获取当前用户点赞的所有评论ID
        liked_ids = CommentLike.objects.filter(user=current_user).values_list('comment_id', flat=True)
        # 遍历评论添加状态属性
        for comment in comments:
            comment.is_liked = comment.id in liked_ids
    else:
        for comment in comments:
            comment.is_liked = False

    return render(request, 'comment_list.html', {'comments': comments})

注意事项

  • CommentLike必须设置unique_together约束,防止同一用户重复点赞同一条评论。
  • 务必处理未登录用户的情况,避免因request.user匿名导致的报错,默认将is_liked设为False。
  • 数据量较大时优先选择方法一,数据库注解的查询效率远高于内存中遍历处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:52:52