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
相关产品推荐
相关产品推荐

