Ограничить prefetch_related до 1 по определенному критерию

У меня есть такие модели

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 на основе всех case-статусов, работает следующий запрос:

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, используя limit 1. Но я не уверен, как я могу заставить это работать в Django ORM.

Вы можете аннотировать свои дела по их последнему статусу, а затем отфильтровать по этому статусу то, что вам нужно.

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)

Вернуться на верх