2011-07-12 66 views
2

我目前正在使用Django,我的模型是這樣的。Django - ForeignKey問題。有多少數據庫訪問?

class City(models.Model): 
    name = models.CharField(max_length=255, primary_key=True) 
    url = models.URLField() 

class Paper(models.Model): 
    city = models.ForeignKey(City) 
    name = models.CharField(max_length=255) 
    price = models.IntegerField() 

class Article(models.Model): 
    paper = models.ForeignKey(Paper) 
    name = models.CharField(max_length=255) 

我想通過篩選城市名稱和紙張價格來獲取City對象,幾個Paper對象和多個Article對象。

進行搜索City表我可以這樣做:

cities = City.objects.get(pk='Toronto') 

要拿到試卷對象:

papers = Paper.objects.filter(city=cities, price < 5) 

或者我甚至可以將二者結合起來:

papers = cities.paper_set.filter(city=cities, price < 5) 

(這會更有效率嗎?)

問題是要找到一種有效的方式來獲取上述'論文'中的所有文章。

我無法使用papers.article_set,因爲論文是QuerySet。如果我嘗試使用一個循環,它可能會爲每個紙張對象進行一次查詢,對吧?

僅供參考城市表有1000列,每個城市有1-1000個紙對象,每個紙對象約有10個物品對象。

任何幫助將非常感激。

謝謝。

編輯: 假設我有一個城市的查詢集(上面),有沒有辦法讓一個查詢中的所有文章對象?

回答

0
articles = Article.objects.all(paper__city__name='Toronto', paper__price__lt=5) 
+0

這會不會比較慢,因爲它需要通過每個文章對象?那麼它不會通過1000 * 500 * 10行? – Maqsood

+0

@Maqsood使用[django-debug-toolbar](https://github.com/robhudson/django-debug-toolbar)來檢查您的查詢。一般來說,連接不會比子查詢慢(通常比較快),但有一些例外。所以我認爲這是一個最佳方法。不要忘記緩存。如果它仍然是一個問題,可能你應該考慮反規範化,但它不認爲你的負載是如此巨大。 – DrTyrsa

1

,因爲試卷是一個QuerySet我不能使用papers.article_set。如果我嘗試使用循環,我可能會根據 紙張對象進行一次查詢,對吧?

如果遍歷查詢集只會執行一條SQL語句。 Django緩存整個查詢集,但如果您只有1000行,這將是沒有問題的。

如果您遍歷大型查詢集使用queryset.iterator():

https://docs.djangoproject.com/en/1.3/topics/db/optimization/

1

你可以得到執行的查詢像這樣(確保DEBUG =在您的settings.py真):

from django.db import connection 
connection.queries 

更多詳細資料可在Django DB FAQ找到。

+0

謝謝。我將用它來測試這些查詢。 – Maqsood