按特定条件限制 prefetch_related 为 1

Limit prefetch_related to 1 by a certain criteria

所以我有这样的模型

class Status(models.Mode):
    name = models.CharField(max_length=255, choices=StatusName.choices, unique=True)

class Case(models.Model):
    # has some fields

class CaseStatus(models.Model):
    case = models.ForeignKey("cases.Case", on_delete=models.CASCADE, related_name="case_statuses")
    status = models.ForeignKey("cases.Status", on_delete=models.CASCADE, related_name="case_statuses")
    created = models.DateTimeField(auto_now_add=True)

我需要根据案例状态过滤案例,但问题是只应考虑最新的案例状态。

要根据所有案例状态获取案例对象,此查询有效:

Case.objects.filter(case_statuses__status=status_name)

但我需要获取 Case 对象,以便仅考虑其最新的 case_status 对象(降序创建)。我正在寻找这样的东西:

Case.objects.filter(case_statuses__order_by_created_first__status=status_name)

我也尝试过 Prefetch,但似乎不适用于我的用例

sub_query = CaseStatus.objects.filter(
id=CaseStatus.objects.select_related('case').order_by('-created').first().id)

Case.objects.prefetch_related(Prefetch('case_statuses', queryset=sub_query)).filter(
case_statuses__status=status_name)

这在原始 postgres 中使用限制 1 很容易解决。但不确定如何在 Django ORM 中实现它。

您可以 annotate 您的案例及其最后状态,然后根据您想要的状态过滤。

from django.db.models import OuterRef

status_qs = CaseStatus.objects.filter(case=OuterRef('pk')).order_by('-created').values('status__name')[:1]
Case.objects.annotate(last_status=status_qs).filter(last_status=status_name)