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

如何在Django模板中判断当前登录用户是否点赞过帖子?

问题描述

我有如下Django模型结构:

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    text = models.CharField(max_length=1200, blank=True)

class PostLike(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

模板代码片段如下:

{% for post in posts %}
...
# 想要在此处判断当前登录用户是否点赞过该帖子,比如:
{% if post.userliked %}显示已点赞{% endif %}
...
{% endfor %}

我希望在Django模板中判断当前登录用户是否点赞过该帖子,尝试过用post.postlike_set但它返回所有点赞记录,没法直接判断,求可行的解决方法。


解决方法

方法一:在Post模型中添加判断方法

直接在Post模型里新增一个方法,接收当前用户并判断是否存在对应的点赞记录:

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    text = models.CharField(max_length=1200, blank=True)

    def is_liked_by(self, user):
        if user.is_anonymous:
            return False
        return PostLike.objects.filter(post=self, user=user).exists()

模板中直接调用该方法:

{% for post in posts %}
    {% if post.is_liked_by(user) %}
        <span>已点赞</span>
    {% else %}
        <span>未点赞</span>
    {% endif %}
{% endfor %}

注:模板默认可通过user获取当前登录用户,匿名用户会直接返回False。

方法二:视图中预处理帖子列表(避免N+1查询)

如果帖子数量较多,方法一会触发N+1查询(每个帖子单独查询点赞表),性能较差。可以在视图层批量处理:

方式A:用annotate+Exists子查询

from django.db.models import Exists, OuterRef

def post_list(request):
    user = request.user
    posts = Post.objects.all()
    if user.is_authenticated:
        posts = posts.annotate(
            userliked=Exists(
                PostLike.objects.filter(post=OuterRef('pk'), user=user)
            )
        )
    return render(request, 'post_list.html', {'posts': posts})

模板中直接使用post.userliked判断:

{% for post in posts %}
    {% if post.userliked %}
        <span>已点赞</span>
    {% else %}
        <span>未点赞</span>
    {% endif %}
{% endfor %}

方式B:批量获取已点赞帖子ID

def post_list(request):
    user = request.user
    posts = Post.objects.all()
    liked_post_ids = []
    if user.is_authenticated:
        liked_post_ids = PostLike.objects.filter(user=user).values_list('post_id', flat=True)
    # 给每个帖子添加userliked属性
    for post in posts:
        post.userliked = post.id in liked_post_ids
    return render(request, 'post_list.html', {'posts': posts})

这种方式同样能避免N+1查询,适合不需要复杂ORM操作的场景。

方法三:自定义模板过滤器

创建自定义模板过滤器,直接在模板中判断:

  1. 在你的app目录下创建templatetags文件夹,新建post_tags.py文件:
from django import template
from .models import PostLike

register = template.Library()

@register.filter
def is_liked(post, user):
    if user.is_anonymous:
        return False
    return PostLike.objects.filter(post=post, user=user).exists()
  1. 在模板头部加载过滤器:
{% load post_tags %}
  1. 使用过滤器判断:
{% for post in posts %}
    {% if post|is_liked:user %}
        <span>已点赞</span>
    {% else %}
        <span>未点赞</span>
    {% endif %}
{% endfor %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 23:50:23