id | 评论 | answer_id | question_id |
---|---|---|---|
1 | 一些评论 | 2 | 1 |
2 | 一些评论 | 2 | 1 |
3 | 一些评论 | 42 | 1 |
4 | 一些评论 | 42 | 1 |
5 | 一些评论 | 42 | 1 |
6 | 一些评论 | 42 | 1 |
7 | 一些评论 | 2 | 1 |
8 | 一些评论 | 2 | 1 |
9 | 一些评论 | 2 | 1 |
10 | 一些评论 | 2 | 1 |
11 | 一些评论 | 2 | 1 |
12 | 一些评论 | 42 | 1 |
13 | 一些评论 | 2 | 1 |
14 | 一些评论 | 2 | 1 |
15 | 一些评论 | 2 | 1 |
16 | 一些评论 | 2 | 1 |
17 | 一些评论 | 42 | 1 |
18 | 一些评论 | 42 | 1 |
19 | 一些评论 | 42 | 1 |
20 | 一些评论 | 42 | 1 |
21 | 一些评论 | 42 | 1 |
以上是姓名表
Comment
,其中包含答案和问题的评论。Answer
和Question
,其中包含问题和答案的数据。
我只想获取每个 answer_id 的前 5 个记录,即该特定问题_id 的(
2
和 42
),即(1
)。
以下是我试过的查询,
answer = Answer.objects.filter(question=question_id)
answer_comment = Comment.objects.filter(answer_id__in=answer.values('id'))
但是上面的查询给出了特定问题的所有数据。
鉴于您说的是“默认顺序”,我假设您希望“前 5 条评论”表示给定问题的每个答案(id
question_id
在这个例子中)。还假设“5 个或更少”(一个答案可能只有 3 个评论)
为了实现这一点,我会像这样使用窗口函数(Django docs,MySQL docs):
from django.db.models import F, Window
from django.db.models.functions import RowNumber
n_comments_per_answer = 5
comments = Comment.objects.filter(
answer__question_id=question_id
).annotate(
row_number=Window(
expression=RowNumber(),
# question_id isn't actually required in the partition_by since
# you only require answers of one question but will be if you
# remove this filter
partition_by=[F('question_id'), F('answer_id')],
order_by=answer_id
)
).filter(
row_number__lte=n_comments_per_answer
)
另一个更简单的解决方案,如果你不介意在一个查询集中没有所有的评论,而是作为一个可迭代的,那就是只提取每个答案和他们对一个问题的相关评论,并在 python 中完成工作:
answers = Answer.objects.prefetch_related('comment_set').filter(question_id=question_id)
# using a list but it could be a generator expression too
comments = [
comment
for answer in answers
for comment in list(answer.comment_set.all())[:5]
]