2016-03-15 70 views
2

排序如何使用procedurestatus_set過濾具有最後Status'1'的Procedure模型。Django查詢集:按反向鍵過濾,並按

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作任何 Statusprocedurestatus_set)與status 1,但不是那些最後Status.status爲1

如何可以我通過驗證篩選Procedure他們最後的Status

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

我使用Django 1.9。

+3

您在這裏沒有狀態日期,那麼'最後'狀態是什麼?最大的主鍵? – Alasdair

回答

1

假設「最後」是指最大的PK,你想查詢所有Procedure情況下,其最後Statusstatus==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需要兩個濾波器查詢不被合併到一個過濾器表達式中,當數據庫被實際訪問時(這個django會這樣做),你必須使用這個嵌套表達式和id__in

在手邊的情況下,嵌套的(內)order_by濾波器組Status通過procedure_id和降序pk對其進行排序,所述distinct每個Procedure(注意選擇第一(最大pkStatusdistinct與場參數是唯一的Postgres支持一些caveats)。然後,您可以將任何其他篩選器應用於外部QuerySet。

Django ORM應該將整體轉換成一個查詢到數據庫。

+0

感謝schwobaseggl,它在使用這兩個查詢時很有魅力! –