2011-02-04 77 views
2

假設你有兩個模型:PostCategory。每個Post有一個category_id在沒有循環引用的Django中雙向查詢

獲取帖子的類別很簡單:post.category。如果你想獲得某個類別的所有帖子怎麼辦?我想你會做

def posts(self): 
    return Post.filter(category__pk=self.id) 

但如果Post模型和Category模型在不同的文件是什麼?由於PostCategory現在需要彼此,您最終會得到循環引用。

也許你說的解決辦法是把PostCategory放到同一個文件中。但是,如果你的應用程序有50個不同的模型,其中很多很大,都在單獨的文件?你是否應該將PostCategory合併爲一個文件並將所有其他文件分開?你應該將所有50個模型合併成一個巨大的文件嗎?

,我希望能找到一兩件事情:

  1. 回答這個問題,不涉及合併的文件
  2. 好,用於分組模式與一個相同的文件邏輯上的理由另一個。我所有的模特都有一定程度的關聯,所以在分組進行的時候,哪裏畫線?如果你用外鍵畫線,我所有的模型都會在同一個文件中。
+0

「你最終會得到循環引用」。這個假設是完全錯誤的。你爲什麼這麼說? – 2011-02-04 17:45:07

+0

我試過了,發生了什麼事。 – 2011-02-04 17:50:08

回答

2

您可以通過名稱(即字符串)而不是實際對象來引用模型。他們在單獨的應用程序?在這種情況下,你可以參考他們使用點符號作爲documentation on ForeignKey描述:

#in mysite/categories/models.py 
class Category(models.Model): 
    ... 


#in mysite/posts/models.py 
class Post(models.Model): 
    category = models.ForeignKey('categories.Category') 

您也可以導入一個函數中的模型,而不是在文件的頂部。我經常這樣做是爲了避免循環引用:

def posts(self): 
    from posts.models import Post 
    return Post.filter(category__pk=self.id) 
3

對於你的問題的第1部分:

的Django自動爲您設置的反向關係。在你的目錄,你可以使用一個post_set屬性,它本身就是一個Manager,所以你可以做:

def posts(self): 
    return self.post_set.all() 

退房the docs更多關於這一點。

對於第2部分。我有一個不太完整的答案......如果您遇到需要將模型分解成如此多的文件,您可能會遇到更根本的問題。我想說你應該考慮把這個龐大的應用分解成一些小應用。

我認爲我在減少應用程序大小方面的最好建議是「做一件事」。如果你的應用不能用一個相對較短的短語來描述,那麼值得考慮如何將它分解成多個較小的應用 - 每一個應用都會「做一件事」。

這個建議當然相當有用。需要相當多的計劃來弄清楚如何分解一些複雜的任務,有時候後視是查看事情失控的唯一方法。重構你所說的大小的東西可能是相當艱鉅的。 (如果你可以告訴我是憑經驗說話!)。在這種情況下,我唯一的建議是逐步採取一步。嘗試將看起來像是大型的應用程序跨越式問題分解成小的,可管理的塊,並儘可能地做到這一點。

爲了解決您的緊急需求,我建議您將模型分爲局部或絕對分組。它可能會引導您將這一個(聽起來像一個龐然大物)應用程序重構爲一些較小的應用程序。我認爲這是你真正應該朝這個方向發展的方向。