2010-05-15 2 views
2

Вот моя упрощенная модель:Джанго агрегирование запросов на связанных один-ко-многим объектам

class Item(models.Model): 
    pass 

class TrackingPoint(models.Model): 
    item = models.ForeignKey(Item) 
    created = models.DateField() 
    data = models.IntegerField() 

    class Meta: 
     unique_together = ('item', 'created') 

Во многих частях моего приложения мне нужно, чтобы получить набор Item-х и аннотировать каждый элемент с data поле от последних TrackingPoint от каждого товара, заказанного created. Например, экземпляр i1 класса Item имеет 3 TrackingPoint «S:

tp1 = TrackingPoint(item=i1, created=date(2010,5,15), data=23) 
tp2 = TrackingPoint(item=i1, created=date(2010,5,14), data=21) 
tp3 = TrackingPoint(item=i1, created=date(2010,5,12), data=120) 

мне нужна запрос для получения i1 экземпляра аннотированного с tp1.data значения поля в качестве tp1 является последней точкой слежения по заказу created поля. Этот запрос также должен вернуть Item, у которого нет TrackingPoint. Если возможно, я предпочитаю не использовать метод QuerySetextra для этого.

Вот что я пытался до сих пор ... и не :(

Item.objects.annotate(max_created=Max('trackingpoint__created'), 
         data=Avg('trackingpoint__data')).filter(trackingpoint__created=F('max_created')) 

Любые идеи?

ответ

1

Это прямо не ответил на ваш вопрос, но в случае, если не нужно точно вы описали, вы можете быть заинтересованы в решении величайшая-н-погруппной вы посмотрите на мой ответ на подобный вопрос может:.

Django Query That Get Most Recent Objects From Different Categories

- т его следует обратиться непосредственно к вашему делу:

items = Item.objects.annotate(tracking_point_created=Max('trackingpoint__created')) 
trackingpoints = TrackingPoint.objects.filter(created__in=[b.tracking_point_created for b in items]) 

Обратите внимание, что вторая линия может производить неоднозначные результаты, если created сроков повторить в модели TrackingPoint.

+0

Ваше решение проходит через все «предметы», я не могу этого себе позволить. 'created' уникален в пределах одного элемента, я обновил свой вопрос. – parxier

6

Вот один запрос, который будет предоставлять (TrackingPoint, Item) -парами:

TrackingPoint.objects.annotate(max=Max('item__trackingpoint__created')).filter(max=F('created')).select_related('item').order_by('created') 

Вы бы должны запрашивать товары без TrackingPoints отдельно.

+0

Спасибо, это сработало отлично! – Jeff

+0

не знал о select_related - cheers – frankster