注: 此处的小评论涉及数据库操作
初级小评论代码
settings.py
INSTALLED_APPS = [ ... 'app01', # 注册app ] STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号 TEMPLATES = [ ... 'DIRS': [os.path.join(BASE_DIR, 'templates')], ]
urls.py
from django.contrib import admin from django.urls import path from django.conf.urls import url, include from app01 import views urlpatterns = [ # 评论 url('comment/', views.Node.Comment) ]
views.py
from django.shortcuts import render from django.shortcuts import redirect from django.shortcuts import HttpResponse from app01 import models class Node: @staticmethod def digui(ret, row): for item in ret: if row['parent_id'] == item['id']: row['children'] = [] item['children'].append(row) break else: Node.digui(item['children'], row) @staticmethod def create_commen_tree(comment_list): ret = [] ''' ret=[ {'id':1, 'content':'Python', 'user':'AAA', 'parent_id': None, 'children':[]}, {'id':2, 'content':'JAVA', 'user':'AAA', 'parent_id': None, 'children':[]}, {'id':3, 'content':'C++', 'user':'AAA', 'parent_id': None, 'children':[]} ] ''' for row in comment_list: if not row['parent_id']: row['children'] = [] ret.append(row) else: Node.digui(ret, row) return ret # 评论 def Comment(request): ''' 【标准】方式一:这里是从数据库内取值 news_id = 1 # 获取新闻id=1的新闻,页面不能直接循环,否则显示不出来层级关系 commen_list = models.Comment.objects.filter(news_id=news_id) for row in commen_list: print(row.id, row.content, row.userInfo.name, row.parent_id) return HttpResponse("OK") ''' # 方式二: 这里是模仿来实现评论的级别关系 comment_list = [ {'id':1, 'content':'Python', 'user':'AAA', 'parent_id': None}, {'id':2, 'content':'JAVA', 'user':'AAA', 'parent_id': None}, {'id':3, 'content':'C++', 'user':'AAA', 'parent_id': None}, {'id':4, 'content':'PHP', 'user':'BBB', 'parent_id': 1}, {'id':5, 'content':'HTML', 'user':'CCC', 'parent_id': 1}, {'id':6, 'content':'CSS', 'user':'DDD', 'parent_id': 4}, {'id':7, 'content':'JavaScript', 'user':'EEE', 'parent_id': 2}, {'id':8, 'content':'Python', 'user':'FFF', 'parent_id': 3}, {'id':9, 'content':'C#', 'user':'GGG', 'parent_id': 2}, {'id':10, 'content':'Shell', 'user':'HHH', 'parent_id': 4}, {'id':11, 'content':'C语言', 'user':'XXX', 'parent_id': 6}, ] comment_tree = Node.create_commen_tree(comment_list) for item in comment_tree: print(item) return HttpResponse("OK")
models.py
from django.db import models # Create your models here. # 新闻表 class News(models.Model): title = models.CharField(max_length=32) # 用户表 class UserInfo(models.Model): name = models.CharField(max_length=32) # 评论表 class Comment(models.Model): content = models.CharField(max_length=150) userInfo = models.ForeignKey("UserInfo", on_delete=True) news = models.ForeignKey("News", on_delete=True) parent = models.ForeignKey("self", on_delete=True, related_name='o', null=True) ctime = models.DateTimeField(auto_now_add=True, null=True)
页面显示;
初始化数据库
python manage.py makemigrations python manage.py migrate
高级小评论代码
原理解析:
因为li[列表]是引用类型,所以v和li引用同一个地址,v增加后li也同时增加
li = [ [1,2,3,4,5], [1,2,3,4,5,6], ] v = li v.append([000,111,222]) print(li) print(v)
同上原理,每个字典更改后,其内部的内容包括引用的内容都会修改
li = [ {'id': 10, 'content': 'Shell', 'user': 'HHH', 'parent_id': 4}, {'id': 11, 'content': 'C语言', 'user': 'XXX', 'parent_id': 6}, ] v = li for item in li: item.update({'children' : []}) # 每个列表里面添加children属性,有则更改,无责添加 print('li里的元素: ', li) # 为每隔row添加children属性 for row in li: if row['id'] == 11: row['children'].append(row) li[1]['user'] = 'FTL' # 此时li[1]里面的内容全部修改了包括内部children中的name # 在item里的children元素添加item内容 for item in li: print('children添加元素: ', item, item['children'])
内容显示:
小评论高级算法:
comment_list = [ {'id':1, 'content':'Python', 'user':'AAA', 'parent_id': None}, {'id':2, 'content':'JAVA', 'user':'AAA', 'parent_id': None}, {'id':3, 'content':'C++', 'user':'AAA', 'parent_id': None}, {'id':4, 'content':'PHP', 'user':'BBB', 'parent_id': 1}, {'id':5, 'content':'HTML', 'user':'CCC', 'parent_id': 1}, {'id':6, 'content':'CSS', 'user':'DDD', 'parent_id': 4}, {'id':7, 'content':'JavaScript', 'user':'EEE', 'parent_id': 2}, {'id':8, 'content':'Python', 'user':'FFF', 'parent_id': 3}, {'id':9, 'content':'C#', 'user':'GGG', 'parent_id': 2}, {'id':10, 'content':'Shell', 'user':'HHH', 'parent_id': 4}, {'id':11, 'content':'C语言', 'user':'XXX', 'parent_id': 6}, ] ''' 方法一: for循环,效率低 ret = [] for it in comment_list: it.update({'children': []}) for item in comment_list: current_row = item current_row_parentId = current_row['parent_id'] if not current_row_parentId: ret.append(current_row) else: for row in comment_list: # 效率低,从头到尾又循环了一遍 if row['id'] == current_row_parentId: row['children'].append(item) print(ret) ''' # 方法二: 利用字典的get效率更高,因为字典的key会转换为哈希字符串,get相当于根据sql里面的索引查找 ret = [] comment_list_dict={} for item in comment_list: item.update({"children":[]}) #有则更改,无责添加: comment_list_dict={1:{'id':1, 'content':'Python', 'user':'AAA', 'parent_id': None},} comment_list_dict[item['id']]=item for row in comment_list: current_now_parentID = row['parent_id'] parent_row = comment_list_dict.get(current_now_parentID) # 找到了父级row if not parent_row: ret.append(row) else: parent_row['children'].append(row) # 直接给父级row的children添加当前元素 print(ret)
小评论高级完整版[前台处理数据,推荐使用]
settings.py
INSTALLED_APPS = [ ... 'app01', # 注册app ] STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号 TEMPLATES = [ ... 'DIRS': [os.path.join(BASE_DIR, 'templates')], ]
urls.py
from django.contrib import admin from django.urls import path from django.conf.urls import url, include from app01 import views urlpatterns = [ # 评论 url('comment/', views.comment), url('index/', views.index), ]
views.py
from django.shortcuts import render, redirect, HttpResponse from app01 import models #小评论高级算法 def comment(request): ''' 数据库的操作: nid = request.GET.get('nid') comment_list=models.obects.filter(nid=nid).values('id',...) # 利用value进行字段内容的获取 commont_list --> ret [进行树形结构的转换,这里直接用固定的内容演示] ''' comment_list = [ {'id':1, 'content':'Python', 'user':'AAA', 'parent_id': None}, {'id':2, 'content':'JAVA', 'user':'AAA', 'parent_id': None}, {'id':3, 'content':'C++', 'user':'AAA', 'parent_id': None}, {'id':4, 'content':'PHP', 'user':'BBB', 'parent_id': 1}, {'id':5, 'content':'HTML', 'user':'CCC', 'parent_id': 1}, {'id':6, 'content':'CSS', 'user':'DDD', 'parent_id': 4}, {'id':7, 'content':'JavaScript', 'user':'EEE', 'parent_id': 2}, {'id':8, 'content':'Python', 'user':'FFF', 'parent_id': 3}, {'id':9, 'content':'C#', 'user':'GGG', 'parent_id': 2}, {'id':10, 'content':'Shell', 'user':'HHH', 'parent_id': 4}, {'id':11, 'content':'C语言', 'user':'XXX', 'parent_id': 6}, ] ret = [] comment_list_dict={} for item in comment_list: item.update({"children":[]}) # 有则更改,无责添加: comment_list_dict={1:{'id':1, 'content':'Python', 'user':'AAA', 'parent_id': None},} comment_list_dict[item['id']]=item for row in comment_list: current_now_parentID = row['parent_id'] parent_row = comment_list_dict.get(current_now_parentID) # 找到了父级row if not parent_row: ret.append(row) else: parent_row['children'].append(row) # 直接给父级row的children添加当前元素 print(ret) import json return HttpResponse(json.dumps(comment_list)) def index(request): return render(request, 'index.html')
models.py[未用到,静态数据源]
from django.db import models # Create your models here. # 新闻表 class News(models.Model): title = models.CharField(max_length=32) # 用户表 class UserInfo(models.Model): name = models.CharField(max_length=32) # 评论表 class Comment(models.Model): content = models.CharField(max_length=150) userInfo = models.ForeignKey("UserInfo", on_delete=True) news = models.ForeignKey("News", on_delete=True) parent = models.ForeignKey("self", on_delete=True, related_name='o', null=True) ctime = models.DateTimeField(auto_now_add=True, null=True)
templates/comment.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> </body> </html>
templates/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> .comment-box { margin-left: 10px; } </style> </head> <body> <div class="item"> <h2>[静态演示效果]</h2> <a nid="17" class="com">评论</a> {#comment-box表示一个评论#} <div class="comment-list"> <div class="comment-box"> <span>Python开发</span> <div class="comment-box"> <span>Java开发</span> <div class="comment-box"> <span>C开发</span> </div> </div> <div class="comment-box"> <span>PHP开发</span> </div> </div> <div class="comment-box"> <span>手机厂商</span> <div class="comment-box"> <span>Huawei</span> <div class="comment-box"> <span>XiaoMi</span> </div> </div> <div class="comment-box"> <span>Apple</span> </div> </div> </div> </div><hr> <div class="item"> <h3>动态演示效果,点击显示评论</h3> <a nid="18" class="com">评论</a> </div><hr> </body> <script src="/static/jquery-2.1.4.min.js"></script> <script> // 页面加载完成后实现绑定小姑 $(function () { bindCommentEvent(); }); function bindCommentEvent() { $(".com").click(function () { var news_id = $(this).attr('nid'); console.log(news_id); var $this = $(this); $.ajax({ url:'/comment/', type:'GET', // 一个date引发的错误 data: {nid:news_id}, dataType: "JSON", success: function (args) { console.log(args); create_tree(args, $this); } }) }) } // 递归 function digui(child_data) { var html = ""; $.each(child_data, function (k1, v1) { var b = '<div class="comment-box"><span>'; b += v1.content; b += '</span>'; son = digui(v1.children); b += son; b += '</div>'; html += b; }); console.log("HTML:",html) return html; } function create_tree(data,$this) { var html = '<div class="comment-list">'; {# 注意这里是在函数内获取到key,value,然后从value里面获取内容#} $.each(data, function (k, v) { var a = '<div class="comment-box"><span>'; a += v.content + "</span>"; // 添加子评论 var child = digui(v.children); console.log(child); a += child; a +='</div>'; html += a; }); html += '</div>'; console.log($this); $this.append(html); } </script> </html>
页面显示;
初始化数据库
python manage.py makemigrations python manage.py migrate
小评论最终版[后台进行tempaltetags来处理递归数据,不推荐]
settings.py
INSTALLED_APPS = [ ... 'app01', # 注册app ] STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号 TEMPLATES = [ ... 'DIRS': [os.path.join(BASE_DIR, 'templates')], ]
urls.py
from django.contrib import admin from django.urls import path from django.conf.urls import url, include from app01 import views urlpatterns = [ # 评论 url('comment/', views.comment), url('index/', views.index), ]
views.py
from django.shortcuts import render, redirect, HttpResponse from app01 import models #小评论高级算法 def comment(request): ''' 数据库的操作: nid = request.GET.get('nid') comment_list=models.obects.filter(nid=nid).values('id',...) # 利用value进行字段内容的获取 commont_list --> ret [进行树形结构的转换,这里直接用固定的内容演示] ''' comment_list = [ {'id':1, 'content':'Python', 'user':'AAA', 'parent_id': None}, {'id':2, 'content':'JAVA', 'user':'AAA', 'parent_id': None}, {'id':3, 'content':'C++', 'user':'AAA', 'parent_id': None}, {'id':4, 'content':'PHP', 'user':'BBB', 'parent_id': 1}, {'id':5, 'content':'HTML', 'user':'CCC', 'parent_id': 1}, {'id':6, 'content':'CSS', 'user':'DDD', 'parent_id': 4}, {'id':7, 'content':'JavaScript', 'user':'EEE', 'parent_id': 2}, {'id':8, 'content':'Python', 'user':'FFF', 'parent_id': 3}, {'id':9, 'content':'C#', 'user':'GGG', 'parent_id': 2}, {'id':10, 'content':'Shell', 'user':'HHH', 'parent_id': 4}, {'id':11, 'content':'C语言', 'user':'XXX', 'parent_id': 6}, ] ret = [] comment_list_dict={} for item in comment_list: item.update({"children":[]}) # 有则更改,无责添加: comment_list_dict={1:{'id':1, 'content':'Python', 'user':'AAA', 'parent_id': None},} comment_list_dict[item['id']]=item for row in comment_list: current_now_parentID = row['parent_id'] parent_row = comment_list_dict.get(current_now_parentID) # 找到了父级row if not parent_row: ret.append(row) else: parent_row['children'].append(row) # 直接给父级row的children添加当前元素 print(ret) return render(request,'comment.html', {"ret":ret}) def index(request): return render(request, 'index.html')
models.py[未用到,静态数据源]
from django.db import models # Create your models here. # 新闻表 class News(models.Model): title = models.CharField(max_length=32) # 用户表 class UserInfo(models.Model): name = models.CharField(max_length=32) # 评论表 class Comment(models.Model): content = models.CharField(max_length=150) userInfo = models.ForeignKey("UserInfo", on_delete=True) news = models.ForeignKey("News", on_delete=True) parent = models.ForeignKey("self", on_delete=True, related_name='o', null=True) ctime = models.DateTimeField(auto_now_add=True, null=True)
App01/tempalatetags/hhh.py
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) # 不添加界面只显示源代码,并不进行html渲染
templates/comment.html
{% load hhh %} {% create_tree ret %}
templates/index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> .comment-box { margin-left: 10px; } </style> </head> <body> <div class="item"> <h2>[静态演示效果]</h2> <a nid="17" class="com">评论</a> {#comment-box表示一个评论#} <div class="comment-list"> <div class="comment-box"> <span>Python开发</span> <div class="comment-box"> <span>Java开发</span> <div class="comment-box"> <span>C开发</span> </div> </div> <div class="comment-box"> <span>PHP开发</span> </div> </div> <div class="comment-box"> <span>手机厂商</span> <div class="comment-box"> <span>Huawei</span> <div class="comment-box"> <span>XiaoMi</span> </div> </div> <div class="comment-box"> <span>Apple</span> </div> </div> </div> </div><hr> <div class="item"> <h3>动态演示效果,点击显示评论</h3> <a nid="18" class="com">评论</a> </div><hr> </body> <script src="/static/jquery-2.1.4.min.js"></script> <script> // 页面加载完成后实现绑定小姑 $(function () { bindCommentEvent(); }); function bindCommentEvent() { $(".com").click(function () { var news_id = $(this).attr('nid'); console.log(news_id); var $this = $(this); $.ajax({ url:'/comment/', type:'GET', // 一个date引发的错误 data: {nid:news_id}, dataType: "html", success: function (args) { console.log('HHH'); console.log(args); {# create_tree(args, $this);#} $this.after(args); } }) }) } /** function digui(child_data) { var html = ""; $.each(child_data, function (k1, v1) { var b = '<div class="comment-box"><span>'; b += v1.content; b += '</span>'; son = digui(v1.children); b += son; b += '</div>'; html += b; }); console.log("HTML:",html) return html; } function create_tree(data,$this) { var html = '<div class="comment-list">'; {# 注意这里是在函数内获取到key,value,然后从value里面获取内容#} $.each(data, function (k, v) { var a = '<div class="comment-box"><span>'; a += v.content + "</span>"; // 添加子评论 var child = digui(v.children); console.log(child); a += child; a +='</div>'; html += a; }); html += '</div>'; console.log($this); $this.after(html); } **/ </script> </html>
页面显示;
初始化数据库
python manage.py makemigrations python manage.py migrate