2012-10-14 151 views
1

對於此代碼檢索與後續查詢的初始查詢集:Django的查詢,對查詢集

people_pool = People.objects.filter(last_name__in = last_names) 
for first_name in first_names: 
    for person in people_pool.filter(first_name = first_name): 
     # do something with each person. 

我從Django的查詢集的理解是,查詢實際上不會,直到你「需要」的數據執行,從而可以優化鏈接的查詢集。但是,如果我沒有弄錯,那在這裏似乎對我不利;將執行的第一個查詢本質上將等同於:

People.objects.filter(last_name__in = last_names, first_name = first_name) # for the first first_name in first_names 

並且需要爲每個單個名字查詢數據庫。如果是這種情況,那麼讓Django實際檢索people_pool,然後在檢索到的python對象上運行後續篩選器,使數據庫保持獨立的正確方法是什麼?

+0

你在想什麼?你可能想看看'select_related' – karthikr

+0

我不想獲取相關模型的任何屬性。試圖訪問person的直接字段,但希望以某種方式限制通過由python執行篩選而不是作爲單獨查詢運行的查詢數量。 –

回答

2

爲了不辦爲每個名字一個DB查詢,唯一的辦法是做實際的過濾在Python:

people_pool = People.objects.filter(last_name__in = last_names) 
people = {} 

for person in people_pool: 
    first_name = person.first_name 
    if first_name in first_names: 
     if not first_name in people: 
      people[first_name] = [] 
     people[first_name].append(person) 

for first_name, people_first_name in people.items(): 
    for person in people_first_name: 
     # do something with each person 

如果你願意,你也可以做一些在第一循環( for person in people_pool)。我只是在dict中添加人員,但該步驟不是必需的。

+0

出於某種原因,我的印象是,如果您已經有一個緩存的查詢集,然後進一步過濾該查詢集,那麼它不必在數據庫上運行另一個查詢。我錯了嗎? –

+0

是的。查詢集緩存實際查詢參數,以便稍後可以修改它們。它不會緩存實際的查詢(當然,它只是在你第一次從queryset獲得對象之後)。 https://docs.djangoproject.com/zh/dev/topics/db/queries/#caching-and-querysets – miki725

+0

確實,我錯了。謝謝你讓我走上正確的道路。另見http://seeknuance.com/2010/12/10/a-performance-lesson-on-django-querysets/ –