2011-08-24 66 views
0

我使用django-threadedcomments,但是該問題一般也適用於排序QuerySet。Django - 對線程註釋的QuerySet進行排序

QuerySet中的註釋對象有兩個重要的字段tree_path和submit_date。 tree_path的形式爲「a/b /.../ z」,其中'a'是樹中最高階的索引,'b'是樹中最低階的索引。所以第一個根註釋會有一個'1'的tree_path。該評論的孩子將具有「1/1」的樹形路徑。 '1'的另一個孩子將有一個'1/2'的tree_path。第二個根註釋的根路徑爲'2',等等......

QuerySet「qs」按上述排序,註釋按照線程順序排列,最上面的註釋最長。上面例子的tree_paths看起來像[1,1/1,1/2,2]。我想先用最新評論對每一級評論進行排序。所以QuerySet應該是[2,1,1/2,1/1]。

我該怎麼做?

我可排序只是使用root級別評論:

qs = qs.extra(select={ 'tree_path_root': 'SUBSTRING(tree_path, 1, 1)' }) 
     .order_by('%stree_path_root' % ('-'), 'tree_path') 

但我無法弄清楚如何在同一時間的非根評論排序。我試過類似的東西:

qs = qs.extra(select={ 'tree_path_root': 'SUBSTRING(tree_path, 1, 1)' 
         'tree_path_sec' : 'SUBSTRING(tree_path, 3, 1)'}) 
     .order_by('%stree_path_root' % ('-'), '%stree_path_sec' % ('-'), 'tree_path') 

但是,這破壞了評論的線程。

有什麼建議嗎?謝謝!

回答

3

我知道這已經有一段時間了,因爲你張貼..所以你現在可能有一個答案,或者你可能已經移動。無論如何,這裏你去... :)

你誤解了django-threadedcomments應用程序中的tree_path結構。永遠不會有1/1的tree_path,因爲每個路徑段都是該ThreadedComment的唯一主鍵。

如果你從ThreadedComment 1開始,並添加回復,你會得到一個路徑1/2。那麼如果你添加一個額外的頂級職位,它會得到路徑3。這將使你:

1 
1/2 
3 

如果你再回復到第一後,你會得到:

1 
1/2 
1/4 
3 

現在就着手整理問題。我試圖做一個類似的排序(通過投票分數,類似於reddit),並發現沒有簡單的方法來做到這一點。然而,這裏是你可以使用遞歸方法:(這是醜陋的,慢...但它的出發點)

def sort_comments(tree): 
    final_tree = [] 
    root_comments = [c for c in tree if c.tree_path.count('/') == 0] 
    root_comments.sort(key=lambda comment: comment.submit_date, reverse=True) 
    for comment in root_comments: 
     final_tree.append(comment) 
     append_and_sort_children(final_tree, tree, comment) 
    return final_tree 


def append_and_sort_children(final_tree, tree, parent): 
    children = [c for c in tree if c.parent_id == parent.id] 
    children.sort(key=lambda comment: comment.submit_date, reverse=True) 
    for comment in children: 
     final_tree.append(comment) 
     append_and_sort_children(final_tree, tree, comment) 

利用這一點,只需通過在你的整個查詢集的該型號的意見,python會爲你排序。 :)

這會給你的最終結果:

3 
1 
1/4 
1/2 

如果有人有辦法縮短這個,隨時作出貢獻。

0

如何首先選擇根註釋,排序並選擇子註釋並排序並最終連接兩個集合?這會工作嗎?

相關問題