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

Django问答站点如何实现每个已标记问题仅返回一条对应答案

解决方案

第一步:先修正模型定义的两处笔误

你当前的模型存在两处不符合业务逻辑的错误,先调整正确:

# models.py 修正后
class Question(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=30)
    # 原字段参数错误,BooleanField 不需要传 booleanField 作为参数,可配置默认值
    marked = models.BooleanField(default=False)

class Answer(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    # 原外键指向错误,应该关联 Question 而不是 BlogPost
    question_of = models.ForeignKey(Question, on_delete=models.CASCADE)
    body = models.CharField(max_length=30)

第二步:实现按问题分组各取1条答案的查询

通用方案(兼容所有数据库,包括MySQL、SQLite、PostgreSQL)

用Subquery子查询实现,逻辑是先给每个已标记的问题匹配到它的第一条答案ID,再根据这些ID筛选答案:

# views.py 修正后
from django.db.models import OuterRef, Subquery

def page(request):
    # 子查询:匹配每个问题的第一条答案的主键
    first_answer_subq = Answer.objects.filter(
        question_of=OuterRef("pk")
    ).order_by("pk").values("pk")[:1]
    
    # 最终查询:每个已标记问题仅返回一条答案
    query_2 = Answer.objects.filter(
        question_of__marked=True,
        pk__in=Subquery(first_answer_subq)
    )

    context = {'query_2': query_2}
    return render(request, 'page.html', context)

PostgreSQL专属简化方案

如果你使用的是PostgreSQL数据库,可以直接用distinct指定去重字段实现,写法更简洁:

query_2 = Answer.objects.filter(
    question_of__marked=True
).order_by("question_of", "pk").distinct("question_of")

原写法问题说明

  • 直接加[:1]是对全局结果集切片,只会返回所有符合条件的答案里的第一条,不会按问题分组单独取
  • 无参数的distinct()是对整条记录去重,你的每条答案内容、主键都不相同,所以不会生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 00:54:03