python - build Hierarchical comment tree?
问题描述
I am trying to implement threaded comments in my django project which I want to look like this: data
comment_list = [
{'id': 1, 'content': '...', 'pid': None, 'children_comments': []},
{'id': 2, 'content': '...', 'pid': None, 'children_comments': []},
{'id': 3, 'content': '...', 'pid': 1, 'children_comments': []},
{'id': 4, 'content': '...', 'pid': 3, 'children_comments': []},
{'id': 5, 'content': '...', 'pid': 4, 'children_comments': []},
{'id': 6, 'content': '...', 'pid': 2, 'children_comments': []},
{'id': 7, 'content': '...', 'pid': None, 'children_comments': []},
{'id': 8, 'content': '...', 'pid': 7, 'children_comments': []},
{'id': 9, 'content': '...', 'pid': None, 'children_comments': []},
{'id': 10, 'content': '...', 'pid': 9, 'children_comments': []},
]
for example
1
3
4
5
2
6
7
8
9
10
my code:
new = []
for comment in comment_list:
if comment['pid'] != None:
for i in comment_list:
if i['id'] == comment['pid']:
i['children_comments'].append(comment)
else:
new.append(comment)
i think that is not good
final in django jinjia how to show??
解决方案
Sure.
The algorithm is as follows:
- iterate over the flat list of comments, gathering up comments by their parentage into a
comments_by_parent
mapping - iterate over the list again, assigning
children_comments
from thecomments_by_parent
mapping - get the root-level comments
from collections import defaultdict
comment_list = [
{'id': 1, 'content': '...', 'pid': None},
{'id': 2, 'content': '...', 'pid': None},
{'id': 3, 'content': '...', 'pid': 1},
{'id': 4, 'content': '...', 'pid': 3},
{'id': 5, 'content': '...', 'pid': 4},
{'id': 6, 'content': '...', 'pid': 2},
{'id': 7, 'content': '...', 'pid': None},
{'id': 8, 'content': '...', 'pid': 7},
{'id': 9, 'content': '...', 'pid': None},
{'id': 10, 'content': '...', 'pid': 9},
]
comments_by_parent = defaultdict(list)
for comment in comment_list:
comments_by_parent[comment['pid']].append(comment)
for comment in comment_list:
comment['children_comments'] = comments_by_parent[comment['id']]
root_comments = comments_by_parent[None]
root_comments
will end up looking like this (JSON output for clarity).
[
{
"id": 1,
"content": "...",
"pid": null,
"children_comments": [
{
"id": 3,
"content": "...",
"pid": 1,
"children_comments": [
{
"id": 4,
"content": "...",
"pid": 3,
"children_comments": [
{
"id": 5,
"content": "...",
"pid": 4,
"children_comments": []
}
]
}
]
}
]
},
{
"id": 2,
"content": "...",
"pid": null,
"children_comments": [
{
"id": 6,
"content": "...",
"pid": 2,
"children_comments": []
}
]
},
{
"id": 7,
"content": "...",
"pid": null,
"children_comments": [
{
"id": 8,
"content": "...",
"pid": 7,
"children_comments": []
}
]
},
{
"id": 9,
"content": "...",
"pid": null,
"children_comments": [
{
"id": 10,
"content": "...",
"pid": 9,
"children_comments": []
}
]
}
]
You can then output this in Jinja using a recursive for loop:
<ul>
{%- for comment in root_comments recursive %}
<li>
{{ comment.content }}
{%- if comment.children_comments -%}
<ul>{{ loop(comment.children_comments) }}</ul>
{%- endif %}
</li>
{%- endfor %}
</ul>
推荐阅读
- php - 从 CSV 文件中删除行并自动生成新文件
- hibernate - 如何在Spring Data中实现一个包含两个相同类型实体列表的实体
- sql - 如何在 Postgresql 中按 DISTINCT user_ids 和 GROUP BY 日期的数量计算列的 AVG 值
- python - 读取csv文件有困难
- templates - 在 Kendo 模板中渲染 HTML
- ruby-on-rails - Rails 5 加入过滤器关联
- nginx - nginx.conf 忽略了 nginx-ingress 配置映射片段
- group-by - sas中每个不同观察的平均___?
- matlab - .mat 文件不在脚本中打开
- vb.net - Socket IO 2.0 不会从 VB.NET windows 服务连接