2014-07-21 57 views
1

(對不起,我的英語)Django Threaded Commenting System

我正在學習Python和Django。現在,我的challange正在開發線程通用評論系統。有兩種模式,發佈和評論。

-Post可以評論。

- 評論可以評論。 (無盡/螺紋)

- 不應該是系統中的n + 1查詢問題。 (不管有多少意見,不應該增加查詢的數量)

我現在的機型都是這樣的:

class Post(models.Model): 
    title = models.CharField(max_length=100) 
    content = models.TextField() 

    child = generic.GenericRelation(
     'Comment', 
     content_type_field='parent_content_type', 
     object_id_field='parent_object_id' 
    ) 

class Comment(models.Model): 
    content = models.TextField() 

    child = generic.GenericRelation(
     'self', 
     content_type_field='parent_content_type', 
     object_id_field='parent_object_id' 
    ) 

    parent_content_type = models.ForeignKey(ContentType) 
    parent_object_id = models.PositiveIntegerField() 
    parent = generic.GenericForeignKey(
     "parent_content_type", "parent_object_id") 

是我的模型嗎?我怎樣才能得到所有評論(層次結構)的職位,沒有n + 1查詢問題?

注:我知道mttp和其他模塊,但我想學習這個系統。


編輯:我跑「Post.objects.all().prefetch_related("child").get(pk=1)」命令,這給了我職位及其子評論。但是當我想要獲取子命令的子命令時,新的查詢正在運行。我可以將命令更改爲...prefetch_related("child__child__child...")...,然後再爲每個子父母關係的深度運行一個新的查詢。有沒有人有解決這個問題的想法?

回答

2

如果您想通過單個查詢獲取關於帖子的所有評論,那麼最好將每條評論鏈接到asssociated帖子。您可以使用單獨的鏈接來指示父註釋。

基本上:

class Post(models.Model): 
    ... 
    comments = models.ManyToManyField('Comment') 
    # link to all comments, even children of comments 

class Comment(models.Model): 
    ... 
    child_comments = models.ManyToManyField('Comment') 
    # You may find it easier to organise these into a tree 
    # if you use a parent_comment ForeignKey. That way the 
    # top level comments have no parent and can be easily spotted. 

Post.objects.all().select_related('comments').get(pk=1) 

的多對多在這需要a little extra work建立關聯,因爲它使用一箇中間表。如果你想要一個純粹的one to many,那麼你需要在Comment上的ForeignKey,但是然後你被限制在prefetch_related而不是select_related,這會涉及額外的數據庫命中。

這也更好,因爲您沒有無類型的外鍵引用(您的PostitiveIntegerField)。

然後您需要將註釋排列到樹結構中,但這不在您的問題的範圍之內。