0

我正在使用django-threadedcomments,但是这个问题通常也适用于对 QuerySet 进行排序。

QuerySet 中的评论对象有两个重要的字段,tree_path 和 submit_date。tree_path 的格式为“a/b/.../z”,其中“a”是树中的最高阶索引,“b”是树中的最低阶索引。因此,第一个根注释的 tree_path 将为“1”。该评论的子节点的 tree_path 为“1/1”。“1”的另一个孩子将有一个“1/2”的tree_path。第二个根注释的 root_path 将为“2”,等等...

QuerySet "qs" 的排序如上,注释按线程顺序排列,最旧的注释在顶部。只是上面示例的 tree_paths 看起来像 [1, 1/1, 1/2, 2]。我想先用最新的评论对每个级别的评论进行排序。所以 QuerySet 应该是 [2, 1, 1/2, 1/1]。

我怎样才能做到这一点?

我可以使用以下方法仅对根级别的评论进行排序:

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')

但这会破坏评论的线程。

有什么建议么?谢谢!

4

2 回答 2

4

我意识到自从您发布以来已经有一段时间了..所以您现在可能已经有了答案,或者您已经继续前进。无论如何,给你... :)

您误解了 django-threadedcomments 应用程序中的 tree_path 结构。永远不会有 1/1 的 tree_path,因为每个路径段都是该 ThreadedComment 的唯一主键。

如果您从 ThreadedComment 开始1,并添加回复,您将获得1/2. 然后,如果您添加一个额外的顶级帖子,它将获得 path 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

如果有人有办法缩短此时间,请随时贡献。

于 2012-01-13T20:27:25.970 回答
0

如何先选择根评论,对它们进行排序,然后选择子评论并对其进行排序,最后将两个集合连接起来呢?那会奏效吗?

于 2012-01-14T17:58:07.160 回答