2016-09-29 64 views
0
篩選使用嵌套查詢最新的對象

我有如下關係:如何在Django

class Product(foo): 
    name = models.CharField() 

class Maintenance(foo): 
    product = models.ForeignKey(Product, related_name="maintenances") 
    start = models.DateField() 
    end = models.DateField() 

我想過濾所有產品與最新有(只有最新的)維修對象startend屬性在給定的日期範圍內。

事情是這樣的:

Product.objects.filter(maintenances__last__end__gte=today.now(), maintenances__last__end__lte=today.now()+datetime.timedelta(days=30)) 

回答

1

你可以filter產品上日期的維護的選擇範圍,然後採取使用annotation最新的維護上Max

import datetime as dt 

from django.db.models import Max 

start_date = dt.datetime.now() 
end_date = dt.datetime.now() + dt.timedelta(days=30) 

products = Product.objects.filter(maintenances__start__gte=start_date, maintenances__end__lte=end_date)\ 
          .annotate(most_recent_maint=Max('maintenances__id'))\ 
          .prefetch_related('maintenances') 
1

在一些例如,也可以採用其他方式進行思考:爲每個產品選擇最新的Maintenance對象:

# filter for time range 
maintenances = Maintenance.objects.filter(
    end__gte=today.now(), 
    end__lte=today.now() + datetime.timedelta(days=30) 
) 
# get latest with distinct product id 
maintenances = maintenances.order_by(
    'product_id', '-end' 
).distinct('product_id') 
# do a `select_related` to get all products in the same query 
maintenances = maintenances.select_related('product') 

請注意,將參數傳遞給distinct()僅適用於使用PostgreSQL的情況。

+0

但是,如何爲每個條目選擇最新的維護記錄並確保過濾器僅基於它?如果我按照您提供的方式使用'last_',則不起作用。它試圖將其用作屬性。 –

+1

對不起,只是錯誤地複製了......如果我正確理解你的問題,它應該過濾「維護」對象的'結尾'。使用'distinct_by'和'distinct'應該爲每個'product_id'提供最新的對象。 –

+0

澄清。謝謝。 –