2012-10-23 91 views
2

考慮與出版商表和書籍表瑪使緩存或預Django的反向關係

def Publisher(models.Model): 
    city = models.CharField() 
    ... 

def Book(models.Model): 
    title = models.CharField() 
    publisher = models.ForeignKey(Publisher) 

在我的模板我想顯示其所有的書一定出版商列表。在我看來,我函數獲取所需的出版商喜歡的東西

publishers=Publisher.objects.filter(city='NY') 

然後在我看來,我遍歷出版商和publishers.book_set.all像

{% for p in publishers %} 
.... 
    {% for b in p.book_set.all %} 

可正常工作,只是它顯然擊中該數據庫就像一個億次。

我該如何優化代碼才能讓django只碰到db一次或兩次?

回答

7

在Django中1.4+,使用prefetch_related

Publisher.objects.filter(city='NY').prefetch_related('book_set') 

在Django中< 1.4,使用django-batch-select

+0

@ team-rf如果您不是Django> = 1.4,那麼您必須手動執行此操作。快速谷歌搜索顯示http://blog.roseman.org.uk/2010/01/11/django-patterns-part-2-efficient-reverse-lookups/。 – miki725

+0

我正在運行django 1.4.1,並且mysql和django會生成儘可能多的匹配,因爲沒有prefetch_related ... –

+0

確保您沒有過濾* book_set * *。 'prefetch_related'只能獲取完整的相關查詢集(即和'publisher.book_set.all()'所返回的一樣)。如果過濾'book_set',Django會丟棄預取並在數據庫上運行查詢。如果你需要過濾'book_set',然後看看django-batch-select,它有更多的靈活性,但不像'prefetch_related'那樣無縫。 –