Объекты фильтрации Django на основе значения поля последних данных в другой модели

Есть 2 модели

class A(models.Model): name = models.TextField()

class B(models.Model): a = models.ForeignKey(A) status = models.BooleanField(default=False)

Теперь я хочу отфильтровать объекты класса A на основе последних данных в статусе класса B.

если есть 2 данных модели B

id | a | status 1 | a | True 2 | abc | False 3 | a | False 4 | abc | True

Итак, если я хочу отфильтровать объекты модели A, имеющие статус False. В этом случае это даст мне

a.

Если бы я хотел отфильтровать объекты модели A, имеющие статус True. В этом случае он должен вернуть мне abc.

Я хочу написать запрос что-то вроде

A.objects.filter(b__status__last=True)

Можно ли это сделать с помощью фильтров?


person Pritam Roy    schedule 12.12.2018    source источник
comment
Похоже, что обе строки со статусом False и True содержат abc в вашей таблице. Пожалуйста, подтвердите, вам нужно получить имя класса A, которое находится в последнем созданном экземпляре класса B, который имеет статус True или False? Не получили то, что хотели получить в результате? Набор запросов или значение класса A?   -  person Sergey Pugach    schedule 12.12.2018
comment
Мне нужны все данные класса A, чей последний статус данных в классе B равен True.   -  person Pritam Roy    schedule 12.12.2018
comment
Я обновил вопрос. Проверь это сейчас   -  person Pritam Roy    schedule 12.12.2018


Ответы (2)


Я думаю, вы могли бы эффективно использовать аннотацию здесь.

A.objects.annotate(latest_b=Max("b__created_at")).filter(b__status=True).latest('latest_b')

Здесь мы аннотируем каждый объект A, чтобы он имел поле latest_by, а затем извлекаем последний объект после фильтрации по статусу b. Это должно работать правильно.

person Saad Aleem    schedule 12.12.2018

Пожалуйста, попробуй:

from django.db.models import Max, F

A.objects.annotate(latest=Max('b__id')).filter(b__id=F('latest'),b__status=True)
person Sergey Pugach    schedule 12.12.2018
comment
Хорошее решение, используйте только True вместо 'True' ;-) - person Lucas Moeskops; 12.12.2018