报障系统之多级评论前戏
一、
前戏:
- 列表添加:
v1 = [1,2,3,4] v1.append(123) print(v1) data = [ [11,22,33], [44,55,66] ] data[0].append(data[1]) print(data) # data = [ # [11,22,33, [44,55,66]], # [44,55,66] # ] data[1].append(77) print(data) # data = [ # [11,22,33, [44,55,66,77]], # [44,55,66,77] # ] print(data[0][3]) #[44, 55, 66, 77]
- 字典添加:
v1 = {'k1':'v1'} v1['k2'] = 'v2' print(v1) data = [ {'k1':'v1'}, {'k2':'v2'} ] for item in data: item['kk'] = 'vv' print(data)
案例:
如果parent_id非0,并且parent_id等于id 就添加到id值相同得那行:
# msg_list = [
# {'id':1,'content':'xxx','parent_id':None},
# {'id':2,'content':'xxx','parent_id':None},
# {'id':3,'content':'xxx','parent_id':None},
# {'id':4,'content':'xxx','parent_id':1},
# {'id':5,'content':'xxx','parent_id':4},
# {'id':6,'content':'xxx','parent_id':2},
# {'id':7,'content':'xxx','parent_id':5},
# {'id':8,'content':'xxx','parent_id':3},
# ]
"""
msg_list = [
{
'id':1,'content':'xxx',parent_id:None,child:[
{'id':4,'content':'xxx',parent_id:1},
{'id':5,'content':'xxx',parent_id:1,child:[
{'id':7,'content':'xxx',parent_id:5},
]}]
},
{'id':2,'content':'xxx',parent_id:None,child:[
{'id':6,'content':'xxx',parent_id:2},
]},
{'id':3,'content':'xxx',parent_id:None,child:[
{'id':8,'content':'xxx',parent_id:3},
]},
]
"""
案例代码:
msg_list = [ {'id':1,'content':'xxx','parent_id':None}, {'id':2,'content':'xxx','parent_id':None}, {'id':3,'content':'xxx','parent_id':None}, {'id':4,'content':'xxx','parent_id':1}, {'id':5,'content':'xxx','parent_id':4}, {'id':6,'content':'xxx','parent_id':2}, {'id':7,'content':'xxx','parent_id':5}, {'id':8,'content':'xxx','parent_id':3}, ] # v = [ row.setdefault('child',[]) for row in msg_list] # 列表生成式 msg_list_dict = { } for item in msg_list: item['child']=[] msg_list_dict[item['id']] = item result = [] for item in msg_list: pid = item['parent_id'] if pid: msg_list_dict[pid]['child'].append(item) else: result.append(item) for i in result: print(i)
解题思路:
- 通过冒泡算法进行解答。【推荐】
- 通过for嵌套for循环亦可以实现,但是效率较低。
知识扩展:
二、
Django views中实现:
一层评论:
comment_str = """""" v = """ <div class='comment'> <div class='content'>asdasd</div> <div class='content'>asdasd</div> <div class='content'>asdasd</div> <div class='content'>asdasd</div> </div> """ comment_str += "<div class='comment'>" for row in result: tpl = "<div class='content'>%s</div>" %(row["content"]) comment_str += tpl comment_str += "</div>"
两层评论:
comment_str = """""" v = """ <div class='comment'> <div class='content'>asdasd</div> <div class='content'>asdasd</div> <div class='comment'> <div class='content'>asdasd</div> <div class='content'>asdasd</div> <div class='content'>asdasd</div> </div> <div class='content'>asdasd</div> </div> """ comment_str += "<div class='comment'>" for row in result: tpl = "<div class='content'>%s</div>" %(row["content"]) comment_str += tpl if row['child']: comment_str += "<div class='comment'>" for jow in row['child']: tpl = "<div class='content'>%s</div>" %(jow['content']) comment_str += tpl comment_str += "</div>" comment_str += "</div>"
通过递归实现多级评论:
#views.py #####################评论#################### msg_list = [ {'id': 1, 'content': '写得太好了', 'parent_id': None}, {'id': 2, 'content': '你说得对', 'parent_id': None}, {'id': 3, 'content': '顶楼上', 'parent_id': None}, {'id': 4, 'content': '你眼瞎吗', 'parent_id': 1}, {'id': 5, 'content': '我看是', 'parent_id': 4}, {'id': 6, 'content': '鸡毛', 'parent_id': 2}, {'id': 7, 'content': '你是没啊', 'parent_id': 5}, {'id': 8, 'content': '休息休息吧', 'parent_id': 3}, ] msg_list_dict = { } for item in msg_list: item['child'] = [] msg_list_dict[item['id']] = item ############msg_list_dict用于查找,msg_list result = [] for item in msg_list: pid = item['parent_id'] if pid: msg_list_dict[pid]['child'].append(item) else: result.append(item) ##############打印############# from utils.comment import comment_tree comment_str = comment_tree(result) #utils\comment.py def comment_tree(comment_list): """ :param comment_list: [ {id,:child:[xxx]},{} ] :return: """ comment_str = "<div class='comment'>" for row in comment_list: tpl = "<div class='content'>%s</div>" %(row['content']) comment_str += tpl if row['child']: child_str = comment_tree(row['child']) comment_str += child_str comment_str += "</div>" return comment_str #endpage.html <h3>评论</h3> {{ comment_str|safe }}
三、
前端实现多级评论:
#URL路由 url(r'^comments-(\d+).html',views.comments), #多级评论 #视图函数 #views.py def comments(request,nid): print(nid) response = {'status':True,'data':None,'msg':None} try: msg_list = [ {'id': 1, 'content': '写得太好了', 'parent_id': None}, {'id': 2, 'content': '你说得对', 'parent_id': None}, {'id': 3, 'content': '顶楼上', 'parent_id': None}, {'id': 4, 'content': '你眼瞎吗', 'parent_id': 1}, {'id': 5, 'content': '我看是', 'parent_id': 4}, {'id': 6, 'content': '鸡毛', 'parent_id': 2}, {'id': 7, 'content': '你是没啊', 'parent_id': 5}, {'id': 8, 'content': '休息休息吧', 'parent_id': 3}, ] # v = [ row.setdefault('child',[]) for row in msg_list] # 列表生成式 msg_list_dict = { } for item in msg_list: item['child'] = [] msg_list_dict[item['id']] = item result = [] for item in msg_list: pid = item['parent_id'] if pid: msg_list_dict[pid]['child'].append(item) else: result.append(item) response['data'] = result except Exception as e: response['status'] = False response['msg'] = str(e) return HttpResponse(json.dumps(response)) #模板语言 <h3>评论</h3> <div id="commentArea"></div> <script src="/static/js/jquery-3.2.1.js"></script> <script> /* 1. 调用对象方法时,通过调用类的prototype中的方法,可以扩展 2. 正则表达式 /\w+/g 3. 字符串replace ''.replace('alex','sb'); 指定参数替换 ''.replace(/\w+/,'sb'); 只替换第一个值 ''.replace(/\w+/g,'sb'); 替换全局值 ''.replace(/(\w+)/g,function(k,kk){return 11;}); 加分组替换全局值 */ String.prototype.Format = function (arg) { /* this,当前字符串 "i am {name1}, age is {age9}" arg,Format方法传入的参数 {name:'alex',age:18} return,格式化之后获取的新内容 i am alex, age is 18 */ var temp = this.replace(/\{(\w+)\}/g,function (k,kk) { return arg[kk]; }); return temp; }; $(function () { // 发送Ajax请求,获取所有评论信息 // 列表 // js生成结构 $.ajax({ url: '/comments-{{ obj.nid }}.html', type: 'GET', dataType: 'JSON', success: function (arg) { if (arg.status) { var comment = commentTree(arg.data); $('#commentArea').append(comment) } else { alert(arg.msg) } } }) }); function commentTree(commentList) { var comment_str = "<div class='comment'>"; $.each(commentList, function (k, row) { //var temp = "<div class='content'>" + row.content + "</div>"; var temp = "<div class='content'>{content}</div>".Format({content:row.content}); comment_str += temp if(row.child.length>0){ comment_str += commentTree(row.child); } }); comment_str += '</div>'; return comment_str } </script>
补充:
自定义前端字符串格式化方法:
说明:
python中可以通过format来实现字符串格式化。
Python中是从str中找,前端是从String中找。
前端默认是没有字符串格式化得,但是通过String.prototype可以为前端字符串扩展一个方法。
格式化就是替换。
目的是实现这样得效果:
v1 = "i am {name},age is {age}"
v1.Format({name:'alex',age:18})
例如:
#时间:
dt = new Date()
dt.setDate()
内部就是依赖它来实现得:Date.prototype.getDate = function() {};
#字符串:
var v = 'sdf'
v.charAT()
内部是依赖它来实现得:String.prototype.charAt = function(pos) {};
例子: String.prototype.Format = function (arg) { /* this,当前字符串 arg,Format方法传入的参数 return,格式化之后获取的参数 */ console.log(this,arg); return '666' };
结果:
#加匿名函数例子: v2 = v1.replace(/\{\w+\}/g,function(k){console.log(k)}) 结果: {name} {age} "i am undefined,age is undefined" #加分组例子: v2 = v1.replace(/\{(\w+)\}/g,function(k,kk){console.log(k,kk)}) #函数可以有返回值 结果: {name} name {age} age "i am undefined,age is undefined"