如何在ORM查询中只显示每个外来ID元素的5个元素?

问题描述 投票:0回答:1
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'))

但是上面的查询给出了特定问题的所有数据。

mysql python-3.x django django-templates django-queryset
1个回答
1
投票

鉴于您说的是“默认顺序”,我假设您希望“前 5 条评论”表示给定问题的每个答案(id

question_id 
在这个例子中)。还假设“5 个或更少”(一个答案可能只有 3 个评论)

为了实现这一点,我会像这样使用窗口函数Django docsMySQL 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]
]
© www.soinside.com 2019 - 2024. All rights reserved.