如何根据当前登录用户点赞状态切换社交应用点赞按钮颜色?
实现基于当前用户点赞状态切换按钮颜色
问题分析
你的现有代码通过post.likes(帖子总点赞数)判断按钮颜色,导致只要有用户点赞,所有用户看到的按钮都会变红,无法区分当前登录用户是否点赞。核心问题是判断逻辑错误,应该检查当前用户是否存在该帖子的点赞记录,而不是总点赞数。
解决方案
1. 修改模板判断逻辑(核心)
将模板中的判断条件替换为检查当前用户是否为该帖子的点赞者:
<a href="{% url 'like' post.id %}" class="post__button"> {% if user.is_authenticated and post.post_likes.filter(user=user).exists %} <i class="fa fa-heart" style="color: red; font-size: 27px;"></i> {% else %} <i class="fa-regular fa-heart" style="color: black; font-size: 27px;"></i> {% endif %} </a>
user.is_authenticated:确保只有登录用户才显示个性化状态,未登录用户统一显示黑色空心心post.post_likes.filter(user=user).exists():利用Likes模型中定义的related_name="post_likes",直接查询当前用户是否点赞了该帖子
2. 优化视图性能
原视图中用count()判断是否点赞,替换为exists()更高效(exists()找到匹配项就停止查询,count()会统计所有匹配数):
@login_required def likes(request, post_id): user = request.user post = Post.objects.get(id=post_id) if post.post_likes.filter(user=user).exists(): # 取消点赞 post.post_likes.filter(user=user).delete() post.likes -= 1 else: # 添加点赞 Likes.objects.create(user=user, post=post) post.likes += 1 post.save() return HttpResponseRedirect(reverse('post_detail', args=[post_id]))
3. 解决N+1查询问题(可选)
如果是在帖子列表页面(比如index.html)显示点赞按钮,直接在模板中用filter会导致每个帖子触发一次数据库查询,造成性能问题。可以在列表视图中预加载点赞数据:
# 示例:index视图获取帖子列表时 def index(request): # 预加载所有帖子的点赞记录,避免N+1查询 posts = Post.objects.all().prefetch_related('post_likes') return render(request, 'index.html', {'posts': posts})
内容的提问来源于stack exchange,提问作者Denver
相关产品推荐
相关产品推荐

