Ограничить 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)