2016-03-15 3 views
2

Как фильтровать модели Procedure, которые имеют последние Status в '1', используя procedurestatus_set.Django queryset: Фильтр по обратному ключу и по заказу

class Procedure(models.Model): 
    name = models.CharField(
     max_length=256, 
    ) 

Class Status(models.Model) 
    procedure = models.ForeignKey(
     Procedure, 
    ) 

    status = models.CharField(
     max_length=256, 
    ) 

Procedure.objects.filter(status__status='1') 

В приведенном выше примере, мы можем получить Procedure S, которые имеют какие-либо Status (procedurestatus_set) с status 1, но не те, чей последний Status.status равен 1.

Как я могу фильтровать Procedure путем проверки их последние Status?

Procedure.objects.filter(status__last__status='1')

Я использую Django 1.9.

+3

У вас нет даты статуса, так что же такое «последний» статус? Самый большой первичный ключ? – Alasdair

ответ

1

Предполагая, что «последний» означает большую рк, и вы хотите, чтобы запросить все Procedure экземпляров, последнюю Status имеет status==1, Postgres позволяет следующее:

last_statuses=Status.objects.filter(
    id__in=Status.objects.order_by('procedure_id', '-pk').distinct('procedure_id') 
).filter(status=1) 

procedures = Procedure.objects.filter(id__in=last_statuses.values('procedure_id')) 

для того, чтобы два фильтра, которые необходимы в Status запрос не должен быть объединен в одно выражение фильтра, когда db фактически обращается (что будет делать django), вы должны использовать это вложенное выражение с id__in.

В данном случае стороны, вложенного (внутренние) order_by фильтр группы Status по procedure_id и сортирует их по убыванию pk, то distinct выбирает первый (самый большой pk) Status для каждого Procedure (Примечание: distinct с аргументами поля только поддерживается Postgres с некоторыми caveats). Затем вы можете применить любой другой фильтр к внешнему QuerySet.

Django ORM должен перевести целое в один запрос к базе данных.

+0

Поблагодарите schwobaseggl, он работает как шарм при использовании этих двух запросов! –

Смежные вопросы