2012-10-01 171 views
1

我有一個問題。這兩個屬性會不同,我的意思是db命中。 例如,我們有模型的文章,具有ForeignKeybookdjango和模型的屬性

from django.db import models 

class Article(models.Model): 
    book = models.ForeignKey("books.Book") 

是什麼讓一個author由prorerties的一個最好的辦法:

@property 
def author(self): 
    if self.book: 
     return self.book.author 
    return None 

@property 
def author(self): 
    book = self.book 
    if book: 
     return book.author 
    return None 
+0

Django和蟒蛇明智的,這將是相等的。實際的命中是在你的queryset方法中。 – KillianDS

+0

我不確定我瞭解你的問題。你的兩個選項看起來功能上與我完全相同。我會選擇一個,因爲它有一個較少的線。他們都需要2個查詢:一個用於作者對象,另一個用於該書。但是,如果您使用select_related()選擇作者對象,則可以將其作爲一個參數,它將預先加入書本。 – acjay

回答

2

由於您正在定義Article上的屬性,因此實際的數據庫命中取決於如何檢索Article查詢集。如果在檢索Article對象時在queryset上使用select_related([depth=2]),那麼就數據庫命中而言,這將是最優的,無論您如何編寫屬性。你列出的方式都有類似的表現。

+0

好的,我以爲是,謝謝! –

0

您應該致電

article.book.author 

該調用將查詢書籍對象並將其緩存在文章實例上。所以如果你在第一次調用之後調用article.book.id,它將不會運行第二個查詢。

Personaly我認爲你應該儘量避免在模型方法中碰到數據庫。因爲,隨着應用程序變得複雜,開發人員只需調用文章的作者方法即使他們也擁有書本模型。因爲兩個屬性實際上是相同的。

0

我喜歡這個選項,因爲它使只有一個數據庫查詢:

@property 
def author(self): 
    authors = Author.objects.filter(book__article=self.id)[:1] 
    return authors[0] if authors else None 
+2

但是,無論是否使用'select_related',這種解決方案都會進行查詢。 –

+0

是的,但有時候這是首選。而且,如果你確定在這個過程中'author'字段不會改變,你可以使用'@ memoized_property'而不是'@ property'。 – defuz

+0

@defuz有時不夠好,舉個具體的例子,當這可能是首選,有一個很好的理由。我看不到這個優點。 – KillianDS