2015-09-14 99 views
1

我想使用Django ORM過濾註釋。很多我在這裏發現的,因此文章都是相當過時,在1.2至1.4天針對Django的背:過濾Django註釋的現代方法?

的Django 1.8類似的建議,增加了conditional aggregation,這似乎是我可能想要什麼,但我不能完全弄清楚的語法,我最終會需要。這裏是我的模型,我試圖達到的情況下(我已經簡化了型號爲簡潔起見):

class Project(models.Model): 
    name = models.CharField() 
    ... snip ... 

class Milestone_meta(models.Model): 
    name = models.CharField() 
    is_cycle = models.BooleanField() 

class Milestone(models.Model): 
    project = models.ForeignKey('Project') 
    meta = models.ForeignKey('Milestone_meta') 
    entry_date = models.DateField() 

我想每個Project(與所有的字段),與Max(entry_date)和沿Min(entry_date),對於每個關聯的Milestone,但僅限那些Milestone記錄,其關聯的Milestone_meta標記的is_cycle設置爲True。換句話說:

  • 對於每個項目記錄,給我最大和最小的里程碑entry_dates,但只有當關聯的Milestone_meta將給定標誌設置爲True時。

目前,我得到的項目列表,然後在一個循環中得到MaxMin里程碑,導致N + 1級的數據庫訪問(這得慢,因爲你所期望的):

pqs = Projects.objects.all() 

for p in pqs: 
    (theMin, theMax) = getMilestoneBounds(p) 
    # Use values from p and theMin and theMax 

... 

def getMilestoneBounds(pid): 
    mqs = Milestone.objects.filter(meta__is_cycle=True) 
    theData = mqs.aggregate(min_entry=Min('entry_date'),max_entry=Max('entry_date')) 

    return (theData['min_entry'], theData['max_entry']) 

如何減少這一個或兩個查詢?

+0

我會爭辯說,這絕對是一個額外的甚至原始的sql真的應該被使用的情況。 – e4c5

+0

文檔指出'extra'最終會被棄用。理想情況下,我希望在某種程度上使用一些未來可行的產品。 –

+0

那麼使用更強大,甚至更好的原始sql – e4c5

回答

0

據我所知,你不能在一個查詢中得到所有需要的對象project

不過,如果你並不需要的對象,並且可以只用自己的身份證的工作,辦法之一是─

Milestone.objects.filter(meta__is_cycle=True).values('project').annotate(min_entry=Min('entry_date')).annotate(max_entry=Max('entry_date')) 

它將給具有不同項目的數據類型的字典列表,然後你可以在需要時使用他們的'id'查找對象。