Django评论树的实现
实现django评论树使用了三种方式
第一种方式通过递归实现
缺点:每次查找parent_id的时候都要在ret所有的元素里面找一遍,找不到再在元素的children中寻找,一直找到为止
comment_list = [
{'id': 1, 'content': 'Python最牛逼', 'user': '小李', 'parent_id': None},
{'id': 2, 'content': 'Java最牛逼', 'user': '小李', 'parent_id': None},
{'id': 3, 'content': 'PHP最牛逼', 'user': '小李', 'parent_id': None},
{'id': 4, 'content': '你最牛逼', 'user': '大王', 'parent_id': 1},
{'id': 5, 'content': '我最牛逼', 'user': '张三', 'parent_id': 1},
{'id': 6, 'content': '你最牛逼', 'user': '李四', 'parent_id': 4},
{'id': 7, 'content': '你们都是垃圾...', 'user': '王老五', 'parent_id': 2},
{'id': 8, 'content': '给我点赞哦...', 'user': '赵老六', 'parent_id': 3},
{'id': 9, 'content': '什么东西啊...', 'user': '小李', 'parent_id': 8},
{'id': 10, 'content': '见到你女友,交定你朋友...', 'user': '张三', 'parent_id': None},
{'id': 11, 'content': '大家好,我是大胖...', 'user': '李四', 'parent_id': 6},
]
#评论列表的生成
#第一种方式基本递归,缺点每次查找都需要在ret所有的元素都找一遍,找不到在从儿子里面找一遍
#在在不到在在孙子里面找一遍,知道找到为止。重复寻找。
class Node:
comment_list = [
{'id': 1, 'content': 'Python最牛逼', 'user': '小李', 'parent_id': None},
{'id': 2, 'content': 'Java最牛逼', 'user': '小李', 'parent_id': None},
{'id': 3, 'content': 'PHP最牛逼', 'user': '小李', 'parent_id': None},
{'id': 4, 'content': '你最牛逼', 'user': '大王', 'parent_id': 1},
{'id': 5, 'content': '我最牛逼', 'user': '张三', 'parent_id': 1},
{'id': 6, 'content': '你最牛逼', 'user': '李四', 'parent_id': 4},
{'id': 7, 'content': '你们都是垃圾...', 'user': '王老五', 'parent_id': 2},
{'id': 8, 'content': '给我点赞哦...', 'user': '赵老六', 'parent_id': 3},
{'id': 9, 'content': '什么东西啊...', 'user': '小李', 'parent_id': 8},
{'id': 10, 'content': '见到你女友,交定你朋友...', 'user': '张三', 'parent_id': None},
{'id': 11, 'content': '大家好,我是大胖...', 'user': '李四', 'parent_id': 6},
]
#递归
def digui(ret,row):
for rt in ret:
if rt['id'] == row['parent_id']:
row['children'] =[]
rt['children'].append(row)
return
#ret= [
# {'id': 1, 'content': 'Python最牛逼', 'user': '小李', 'parent_id': None,'children';[
# {'id': 4, 'content': '你最牛逼', 'user': '大王', 'parent_id': 1},
# {'id': 5, 'content': '我最牛逼', 'user': '张三', 'parent_id': 1},
# ]},
# {'id': 2, 'content': 'Java最牛逼', 'user': '小李', 'parent_id': None,'children';[]},
# {'id': 3, 'content': 'PHP最牛逼', 'user': '小李', 'parent_id': None,'children';[]},
# ]
# {'id': 6, 'content': '你最牛逼', 'user': '李四', 'parent_id': 4},
else:
Node.digui(rt['children'],row)
# @property
def create_tree(self,comment_list):
ret = []
for row in comment_list:
if not row['parent_id']: # None
row['children'] = []
ret.append(row)
# [
# {'id': 1, 'content': 'Python最牛逼', 'user': '小李', 'parent_id': None,'children';[]},
# {'id': 2, 'content': 'Java最牛逼', 'user': '小李', 'parent_id': None,'children';[]},
# {'id': 3, 'content': 'PHP最牛逼', 'user': '小李', 'parent_id': None,'children';[]},
# ]
else:#是回复的某个评论
#for i in ret:
# if row['parent_id'] == i['id']:
# i['children'].append(row) #二级评论实现
# else:
# 找三层
Node.digui(ret,row)
return ret
#第一种执行
# print(Node().create_tree(comment_list))
第二种方式通过列表和字典的引用方式查找
缺点是查找的复杂度没有第一种多,但是每次找parent_id还是需要comment_list中全部找一遍,并且还有在comment_list中添加元素,在ret中引用第一层的元素会增加内存的消耗。
#第二种查找方式,字典列表的引用方式
comment_list = [
{'id': 1, 'content': 'Python最牛逼', 'user': '小李', 'parent_id': None},
{'id': 2, 'content': 'Java最牛逼', 'user': '小李', 'parent_id': None},
{'id': 3, 'content': 'PHP最牛逼', 'user': '小李', 'parent_id': None},
{'id': 4, 'content': '你最牛逼', 'user': '大王', 'parent_id': 1},
{'id': 5, 'content': '我最牛逼', 'user': '张三', 'parent_id': 1},
{'id': 6, 'content': '你最牛逼', 'user': '李四', 'parent_id': 4},
{'id': 7, 'content': '你们都是垃圾...', 'user': '王老五', 'parent_id': 2},
{'id': 8, 'content': '给我点赞哦...', 'user': '赵老六', 'parent_id': 3},
{'id': 9, 'content': '什么东西啊...', 'user': '小李', 'parent_id': 8},
{'id': 10, 'content': '见到你女友,交定你朋友...', 'user': '张三', 'parent_id': None},
{'id': 11, 'content': '大家好,我是大胖...', 'user': '李四', 'parent_id': 6},
]
ret = []
for row in comment_list:
row.update({'children':[]})
for item in comment_list:
current_row = item
current_row_parent_id = current_row['parent_id']
if not current_row_parent_id:
ret.append(item)
else:
for r in comment_list:
if r['id'] == current_row_parent_id:
r['children'].append(item) #把有parent_id的数据加入到comment_list对应ID的chilren列表中
#而不是加入到rent中,因为是引用型ret中指向的内存地址是一致的
#缺点,当有不为空的parent_id的元素时,需要找comment_list中找一遍和parent_id相等的ID值,效率比递归的comment_list自身
#和子元素都找一遍的效率高,还有在comment_list中添加元素,在ret中引用第一层的元素会增加内存的消耗。
# print(ret)
# print(comment_list)
第三种方式基于hash查找
基于字典的查找方式
#第三种基于哈希查找,字典存储时会调用Python内部散列函数,将键(Key)作为参数进行转换,得到一个唯一的一个地址,然后将值
#存入这个地址中,所字典的查找也是基于哈希的,所以查找很快速
comment_list = [
{'id': 1, 'content': 'Python最牛逼', 'user': '小李', 'parent_id': None},
{'id': 2, 'content': 'Java最牛逼', 'user': '小李', 'parent_id': None},
{'id': 3, 'content': 'PHP最牛逼', 'user': '小李', 'parent_id': None},
{'id': 4, 'content': '你最牛逼', 'user': '大王', 'parent_id': 1},
{'id': 5, 'content': '我最牛逼', 'user': '张三', 'parent_id': 1},
{'id': 6, 'content': '你最牛逼', 'user': '李四', 'parent_id': 4},
{'id': 7, 'content': '你们都是垃圾...', 'user': '王老五', 'parent_id': 2},
{'id': 8, 'content': '给我点赞哦...', 'user': '赵老六', 'parent_id': 3},
{'id': 9, 'content': '什么东西啊...', 'user': '小李', 'parent_id': 8},
{'id': 10, 'content': '见到你女友,交定你朋友...', 'user': '张三', 'parent_id': None},
{'id': 11, 'content': '大家好,我是大胖...', 'user': '李四', 'parent_id': 6},
]
#创建字典
ret = []
comment_list_dict = {}
for row in comment_list:
row.update({'children':[]})
comment_list_dict[row['id']] = row
print(comment_list_dict)
for item in comment_list:
parent_row = comment_list_dict.get(item['parent_id'])
if not parent_row:
ret.append(item)
else:
parent_row['children'].append(item)
print(ret)
回归前端,使用simple_tag
返回的数据为一个处理好的字典,回归给前端的时候使用自定义模板标签,在Html中调用直接使用模板方法使用
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
def diGui(children_list):
html = ""
for cv in children_list:
b = '<div class="comment-box"><span>'
b += cv['content'] + "</span>"
b += diGui(cv['children'])
b += "</div>"
html += b
return html
@register.simple_tag
def create_tree(comment_list):
html = '<div class="comment-list">'
for v in comment_list:
a = '<div class="comment-box"><span>'
a += v['content'] + "</span>"
a += diGui(v['children'])
a += "</div>"
html += a
return mark_safe(html)
"""
function diGui(children_list){
var html = "";
$.each(children_list,function (ck,cv) {
var b = '<div class="comment-box"><span>';
b+= cv.content + "</span>";
b += diGui(cv.children);
b += "</div>";
html += b;
});
return html;
}
function create_tree(data,$this) {
var html = '<div class="comment-list">';
$.each(data,function (k,v) {
var a = '<div class="comment-box"><span>';
a+= v.content + "</span>";
// 创建自评论
a += diGui(v.children);
a+= "</div>";
html += a;
});
html += "</div>";
$this.after(html);
}
"""
{% load laogao %}
{% create_tree comment_tree %}
<style>
.comment-box{
margin-left: 20px;
}
</style>
HTML
标签:comment,parent,实现,list,Django,content,评论,user,id
From: https://www.cnblogs.com/mengdie1978/p/17374818.html