不知道怎么才能让每个团队都有重复的名字,因为你有unique=True
个.但是,如果您计划删除它以支持非唯一名称,则可以使用如下所示的子查询:
top_3_per_team_name = Team.objects.filter(
name=OuterRef("name")
).order_by("-created_at")[:3]
Team.objects.filter(
id__in=top_3_per_team_name.values("id")
)
虽然这可能会有点慢,但请确保您已经设置了索引.
还要注意的是,理想情况下,这可以通过使用DenseRank
..[Django-doc]的Window
..[Django-doc]个函数来解决,但不幸的是,最新的Django版本不能在Windows上过滤:
from django.db.models import F
from django.db.models.expressions import Window
from django.db.models.functions import DenseRank
Team.objects.annotate(
rank=Window(
expression=DenseRank(),
partition_by=[F('name'),],
order_by=F('created_at').desc()
),
).filter(rank__in=range(1,4)) # 4 is N + 1 if N = 3
有了以上几点,你就能得到:
NotSupportedError: Window is disallowed in the filter clause.
但在Django 4.2上有一个支持这一点的计划,所以从理论上讲,一旦发布,上面的功能应该会起作用.