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

Django点赞功能if和else均执行导致显示两个点赞按钮如何解决

问题根因

你模板中错误遍历了单条回答的所有点赞记录:只要回答有多个用户点赞,就会为每条点赞记录生成一个按钮,自然会同时出现「已点赞」「未点赞」多个按钮,和if/else分支执行逻辑无关。

修复步骤

1. 优化视图层,提前注入用户点赞状态

在question_detail视图里用Django的Exists注解直接给每个回答加上当前用户是否点赞的标记,避免模板层反复查询数据库:

from django.db.models import Exists, OuterRef

def question_detail(request, question_id):
    post = get_object_or_404(Question, pk=question_id)
    # 给每个回答标注当前用户是否点赞
    answers = post.answer_set.annotate(
        is_liked=Exists(
            AnswerLike.objects.filter(
                answer_of=OuterRef('pk'),
                liked_by=request.user if request.user.is_authenticated else None
            )
        )
    )
    context = {'post':post, 'answers':answers}
    return render(request, 'question_detail.html', context)

2. 重写模板逻辑,删除点赞记录遍历

不要循环ans.answerlike_set.all,直接用视图传的is_liked字段判断即可:

{{post}}

{% for ans in answers %}
{{ans.body}}

<form method="POST" class="AnswerLike" action="{% url 'answer_like' ans.id  %}">
    {% csrf_token %}
    {% if ans.is_liked %}
    <button name='submit' type='submit' value="UnLike"><i class="fas fa-thumbs-up"></i>Liked</button>
    {% else %}
    <button name='submit' type='submit' value="Like"><i class="far fa-thumbs-up"></i>Not Liked</button>
    {% endif %}
</form>
{% endfor %}

3. 补全点赞视图的取消逻辑

同时建议把请求方法改成POST,避免GET请求误触发修改操作:

from django.shortcuts import get_object_or_404
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods

@require_http_methods(["POST"])
def answer_like(request, answer_id):
    answer = get_object_or_404(Answer, pk=answer_id)
    user = request.user
    if not user.is_authenticated:
        return JsonResponse({'status':'unlogin'}, status=403)
    # 先查有没有点赞记录
    like_obj = AnswerLike.objects.filter(answer_of=answer, liked_by=user).first()
    if request.POST.get('submit') == 'Like':
        # 没有就创建
        if not like_obj:
            AnswerLike.objects.create(answer_of=answer, liked_by=user)
        return JsonResponse({'status':'liked'})
    elif request.POST.get('submit') == 'UnLike':
        # 有就删除
        if like_obj:
            like_obj.delete()
        return JsonResponse({'status':'unliked'})
额外优化建议

可以给AnswerLike模型加联合唯一约束,避免同一个用户给同一条回答重复点赞:

class AnswerLike(models.Model):
    answer_of = models.ForeignKey(Answer, on_delete=models.CASCADE)
    liked_by = models.ForeignKey(User, on_delete=models.CASCADE)
    
    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['answer_of', 'liked_by'], name='unique_user_answer_like')
        ]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 18:15:01