Django ORM:按列表中的值过滤结果,限制每个值的答案?

Django ORM: Filter results by values from list, limit answers per value?

我正在使用 Django 2.0 并且有一个带有 ForeignKey(User, ...) 的内容模型。我还有一个用户 ID 列表,我想为其获取该内容,按 "newest first" 排序,但每个用户最多只能有 25 个元素。我知道我可以做到:

Content.objects.filter(user_id__in=[1, 2, 3, ...]).order_by('-id')

...获取每个用户创建的所有 Content 对象,此外,我将首先使用最新元素对其进行排序。但我想为每个用户获取最多 25 个元素(有些用户可能创建数百个这样的对象,有些可能创建零个)。当然还有笨办法:

for user in [1, 2, 3, ...]:
    Content.objects.filter(user_id=user).order_by('-id')[:25]

然而,这与用户 ID 列表中的对象一样多地访问数据库,而且数量相当多(每个页面视图大约 100 次左右)。有什么办法可以优化这种情况吗? (我试过环顾四周 select_related,但这似乎能找到尽可能多的相关模型。)

有很多方法可以形成 查询,但在这种情况下,您可以形成所有用户的前 n 个查询的并集:

contents = Content.objects.\
    none().\
    union(*[Content.objects.
            filter(user_id=uid).
            order_by('-id')[:25] for uid in user_ids],
          all=True)

然后使用 prefetch_related(),您可以生成一个查询集来获取用户并注入最新内容的属性:

users = User.objects.\
    filter(id__in=user_ids).\
    prefetch_related(models.Prefetch(
        'content_set',
        queryset=contents,
        to_attr='latest_content'))

它真的多次访问数据库吗?我没有看过原始 SQL 但根据文档,它等同于 LIMIT 子句并且它还声明 "Generally, slicing a QuerySet returns a new QuerySet – it doesn’t evaluate the query".

https://docs.djangoproject.com/en/2.0/topics/db/queries/#limiting-querysets

我很想看看原始的 SQL 如果你正在看它并且它不会这样做,因为我使用这个范例。