1 1、基本表结构 2 class UserInfo(models.Model): 3 username = models.CharField(max_lenght=32,db_index=True) 4 email = models.CharField(max_lenght=32,unique=True) 5 pwd = models.CharField(max_length=64) 6 ################ 最后一次发的时间 ################ 7 ptime = models.DateTimeField(auto_add=True) 8 code = models.CharField(max_length=6) 9 10 """ 11 class Meta: 12 index_together = [ 13 ('username', 'pwd'), 14 ] 15 16 unique_together = [ 17 ('username', 'pwd'), 18 ] 19 """ 20 21 class SendMsg(models.Model): 22 email = models.EmailField(max_lenght=32,unique=True) 23 code = models.CharField(max_length=6) 24 stime = models.DateTimeField() 25 times = models.IntergarField(default=1) 26 27 SendMsg.objects.create(email='11111111',code='123',stime=datetime.now()) 28 # 特殊语句 29 obj = SendMsg(email='11111111',code='123',stime=datetime.now()) 30 obj.clean() 31 obj.save() 32 # django Admin也是可以的 33 34 ?django的Models字段怎么验证? 35 36 2、登录和注册 37 - ORM操作 38 - F 和 Q 39 filter(id__gt=1,name='root') 40 filter(**{"id__gt": 1,...}) 41 filter(Q(Q(id__gt=1)&Q(name="root"))|) 42 (邮箱&密码)| (用户名&密码) 43 - 简单倒计时效果 44 - 验证码 45 - *** 逻辑性处理 *** 46 - 注册成功后,自动登录 47 48 a. 分解注册 49 --- 发送随机验证码 50 前端 51 - 获取邮箱框中的内容,并发到后台(Ajax) 52 - Form验证,只验证一个邮箱 53 class Foo(forms.Form): 54 email ... 55 ret = {'stauts':.., 'summary': ..} 56 不合法: 57 .. 58 合法 59 .. 60 - success回调函数: 61 合法: 62 跑秒 63 不合法: 64 显示错误 65 66 后端: 67 class BaseResponse: 68 def __init__(self): 69 self.status = True 70 self.summary = None 71 self.error = None 72 self.data = None 73 74 class SendMsgForm(forms.Form): 75 email = EmailField(error_messages={'invalid': '邮箱格式错误'}) 76 77 78 def msg(request): 79 #ret = {'stauts': True, 'summary': None, 'error': None, 'data': None} 80 # return HttpResponse(json.dumps(ret)) 81 82 obj = BaseResponse() 83 84 form = SendMsgForm(request.POST) 85 86 if form.is_valid(): 87 # 用户邮箱格式正确 88 89 # 【用户表】中是否已经存在当前邮箱 90 obj.status = False 91 obj.summary = "邮箱已被注册" 92 return return HttpResponse(json.dumps(obj.__dict__)) 93 94 95 【验证码临时表】 96 获取当前时间 97 # 11:11 98 current_date = datetime.datetime.now() 99 code = # 生成随机验证码 random 100 101 102 如果【验证码临时表】有当前邮箱: 103 ====== 1小时,10个数 ====== 104 # 10: 11 105 limit_date = current_date - datetime.datedela(hours=1) 106 # 时间是合理的,次数不合理 107 a = SendMsg.objects.filter(utime__gt=limit_date, times__gt=10).count() 108 # 1小时内次数太多了 109 return 110 111 # 10年后 112 b = SendMsg.objects.filter(utime__lte=limit_date).count() 113 # SendMsg.objects.filter(email=email).update(code=code,stime=current_date,times=1) 114 115 # 116 SendMsg.objects.filter(email=email).update(code=code,times=F('times') + 1) 117 118 else: 119 120 # 数据库的SendMsg创建一条信息 SendMsg.objects.create(... current_date,times=1) 121 # 发送邮件 122 obj.status = True 123 else: 124 obj.summary = form.errors['email'][0] 125 obj.status = False 126 # obj.__dict__ # {'stauts': True, 'summary': None, 'error': None, 'data': None} 127 128 return HttpResponse(json.dumps(obj.__dict__)) 129 130 p 131 -------- 注册 132 a. 获取注册表单中的所有信息,Ajax发送 133 $.ajax({ 134 url: ... 135 data: {.....}, 136 137 }) 138 b. 写Form用于验证用户请求 139 合法: 140 .. 141 不合法: 142 错误信息返回给用户 143 form = registerForm(request.POSt) 144 if form.is_valid(): 145 # 随机验证码进行检查,1分钟内的做的操作 146 【随机验证码的临时表,邮箱,code,code生成的时间】 147 # 获取当前时间 - 1分钟 148 c. 错误信息的展示: 149 -- 详细错误信息 150 151 b. 登录 152 访问首页 153 1、商城验证码图片 <img src='/check_code/'/> session['CheckCode'] = code 154 2、用眼看图片,输入图片上的内容 155 3、用户输入的值和session['CheckCode']进行比较 156 4、用户名和密码的验证 157 models.UserInfo.objects.filter(Q(Q(username=u)&Q(pwd=p))|Q(Q(emial=u)&Q(pwd=p))) 158 159 # {'id': 1,'name': 'root'} 160 161 con = Q() 162 163 q1 = Q() 164 q1.connector = 'AND' 165 166 q1.children.append(('email', e)) 167 q1.children.append(('password', p)) 168 # Q(Q(email=e)&Q(pwd=p)) 169 170 q2 = Q() 171 q2.connector = 'AND' 172 q2.children.append(('username', _value_dict['user'])) 173 q2.children.append(('password', _value_dict['pwd'])) 174 # Q(Q(username=u)&Q(pwd=p)) 175 176 con.add(q1, 'OR') 177 con.add(q2, 'OR') 178 179 models.UserInfo.objects.filter(con) 180 181 验证码 182 - 页面上是图片 183 - 后台字符串且保存在session
1 from django.db import models 2 3 # Create your models here. 4 #临时表 5 class SendMsg(models.Model): 6 nid = models.AutoField(primary_key=True) 7 code = models.CharField(max_length=6) 8 email = models.CharField(max_length=32, db_index=True) 9 times = models.IntegerField(default=0) 10 ctime = models.DateTimeField() 11 #用户表 12 class UserInfo(models.Model): 13 nid = models.AutoField(primary_key=True) 14 username = models.CharField(max_length=32, unique=True) 15 password = models.CharField(max_length=32) 16 email = models.CharField(max_length=32, unique=True) 17 ctime = models.DateTimeField() 18 #新闻类型表,可以不用建该表 19 # class NewsType(models.Model): 20 # caption = models.CharField(max_length=16) 21 #新闻表 22 class News(models.Model): 23 title = models.CharField(max_length=64) 24 summary = models.CharField(max_length=128, null=True)#评论 25 url = models.URLField(null=True) 26 ctime = models.DateTimeField(auto_now_add=True) 27 favor_count=models.IntegerField(default=0)#点赞个数 28 comment_count=models.IntegerField(default=0)#评论个数 29 user = models.ForeignKey(to='UserInfo', to_field='nid', related_name='n') 30 news_type_choices = [ 31 (1, '42区'), 32 (2, '段子'), 33 (3, '图片'), 34 (4, '挨踢1024'), 35 (5, '你问我答'), 36 ] 37 nt = models.IntegerField(choices=news_type_choices)#新闻类型 38 # nt = models.ForeignKey(to='NewsType', to_field='id', related_name='tn') 39 favor=models.ManyToManyField(to='UserInfo') 40 #点赞表,可以直接建在新闻表里 41 # class Favor(models.Model): 42 # user = models.ForeignKey(to='UserInfo', to_field='nid') 43 # news = models.ForeignKey(to='News', to_field='id') 44 #评论表 45 class Comment(models.Model): 46 user = models.ForeignKey(to='UserInfo', to_field='nid') 47 news = models.ForeignKey(to='News', to_field='id') 48 content = models.CharField(max_length=150)#评论内容 49 device = models.CharField(max_length=16,null=True)#用户设备信息 50 ctime = models.DateTimeField(auto_now_add=True)#点赞时间 51 parent_comment = models.ForeignKey(to='self',null=True,related_name='cp')#父评论,用于用户间回复评论
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 .item{ 8 height: 100px; 9 border: 1px solid red; 10 } 11 .zan{ 12 height: 30px; 13 width:30px; 14 background-color: black; 15 color: white; 16 line-height: 30px; 17 text-align: center; 18 position: relative; 19 cursor:pointer; 20 } 21 .zan span{ 22 position: absolute; 23 } 24 </style> 25 </head> 26 <body> 27 <div> 28 <div class="item"> 29 <div class="zan">赞</div> 30 </div> 31 <div class="item"> 32 <div class="zan">赞</div> 33 </div> 34 <div class="item"> 35 <div class="zan">赞</div> 36 </div> 37 <div class="item"> 38 <div class="zan">赞</div> 39 </div> 40 </div> 41 <script src="/static/jquery-3.4.0.js"></script> 42 <script> 43 $(function () { 44 $('.zan').click(function () { 45 var fz = 12; //font-size 46 var tp = 5; //top 47 var lf = 5; //left 48 var op = 1; //opacity 49 var tag = document.createElement('span'); 50 tag.innerText = '+1'; 51 tag.style.color = 'green'; 52 tag.style.fontSize = fz + 'px'; 53 tag.style.top = tp + 'px'; 54 tag.style.left = lf + 'px'; 55 tag.style.opacity = op; 56 $(this).append(tag); 57 var obj = setInterval(function () { 58 fz += 5; 59 tp -= 4; 60 lf += 4; 61 op -= 0.1; 62 tag.style.fontSize = fz + 'px'; 63 tag.style.top = tp + 'px'; 64 tag.style.left = lf + 'px'; 65 tag.style.opacity = op; 66 if (op < 0) { 67 clearInterval(obj); 68 tag.remove(); 69 } 70 }, 100) 71 }) 72 }) 73 </script> 74 </body> 75 </html>
抽屉实现评论数据结构及评论内容显示示例
1.实现评论数据结构两种方式
(1)循环实现评论数据结构(推荐)
(2)js递归实现评论数据结构
2.显示评论内容两种方式
(1)js递归显示评论内容(推荐)
前端进行递归实现
(2)simple_tag递归显示评论内容
render + simple_tag
前端直接after指定位置
1 from django.shortcuts import render,HttpResponse 2 from app01 import models 3 4 def index(request): 5 return render(request, 'index.html') 6 #循环实现评论数据结构(推荐) 7 def comment(request): 8 news_id = request.GET.get('news_id') 9 # models.xxx.filter(news_id=news_id).values(...) 10 comment_list = [ 11 {'id': 1, 'content': 'Python最牛逼', 'user': '搞基建', 'parent_id': None}, 12 {'id': 2, 'content': 'Java最牛逼', 'user': '搞基建', 'parent_id': None}, 13 {'id': 3, 'content': 'PHP最牛逼', 'user': '搞基建', 'parent_id': None}, 14 {'id': 4, 'content': '你最牛逼', 'user': '小比虎', 'parent_id': 1}, 15 {'id': 5, 'content': '老师最你比', 'user': '李欢', 'parent_id': 1}, 16 {'id': 6, 'content': '郭永昌是...', 'user': '郭永昌', 'parent_id': 4}, 17 {'id': 7, 'content': '哈哈我是流氓...', 'user': '崔月圆', 'parent_id': 2}, 18 {'id': 8, 'content': '我女朋友好漂亮...', 'user': '崔月圆', 'parent_id': 3}, 19 {'id': 9, 'content': '见到你女友,交定你朋友...', 'user': '搞基建', 'parent_id': 8}, 20 {'id': 10, 'content': '见到你女友,交定你朋友...', 'user': '鼻环', 'parent_id': None}, 21 {'id': 11, 'content': '我是大胖...', 'user': 'xiaopang', 'parent_id': 6}, 22 ] 23 comment_tree = [] 24 comment_list_dict = {} 25 for row in comment_list: 26 row.update({'children': []}) 27 comment_list_dict[row['id']] = row 28 for item in comment_list: 29 parent_row = comment_list_dict.get(item['parent_id']) 30 if not parent_row: 31 comment_tree.append(item) 32 else: 33 parent_row['children'].append(item) 34 35 import json 36 return HttpResponse(json.dumps(comment_tree)) #JS递归显示评论内容(推荐) 37 #return render(request, 'comment.html', {'comment_tree': comment_tree}) #simple_tag递归显示评论内容
1 from django.shortcuts import render,HttpResponse 2 from app01 import models 3 #递归实现评论数据结构(不推荐) 4 class Node: 5 @staticmethod 6 def digui(ret, row): 7 # ret: {'id': 4, 'content': '你最牛逼', 'user': '小比虎', 'parent_id': 1, 'children': []},{'id': 5, 'content': '老师最你比', 'user': '李欢', 'parent_id': 1},] 8 # row {'id': 6, 'content': '郭永昌是...', 'user': '郭永昌', 'parent_id': 4}, 9 for rt in ret: 10 if rt['id'] == row['parent_id']: 11 row['children'] = [] 12 rt['children'].append(row) 13 return 14 else: 15 Node.digui(rt['children'],row) 16 17 @staticmethod 18 def create_tree(comment_list): 19 ret = [] 20 """ 21 {'user': '搞基建', 'parent_id': None, 'id': 1, 'children': [{'id': 4, 'content': '你最牛逼', 'user': '小比虎', 'parent_id': 1, 'children': []},{'id': 5, 'content': '老师最你比', 'user': '李欢', 'parent_id': 1},], 'content': 'Python最牛逼'} 22 {'user': '搞基建', 'parent_id': None, 'id': 2, 'children': [], 'content': 'Java最牛逼'} 23 {'user': '搞基建', 'parent_id': None, 'id': 3, 'children': [], 'content': 'PHP最牛逼'} 24 """ 25 for row in comment_list: 26 # row {'id': 6, 'content': '郭永昌是...', 'user': '郭永昌', 'parent_id': 4}, 27 if not row['parent_id']: # None 28 row['children'] = [] 29 ret.append(row) 30 else: 31 Node.digui(ret,row) 32 return ret 33 34 def comment(request): 35 news_id = 1 36 37 # comment_list = models.Comment.objects.filter(news_id=news_id) 38 # for row in comment_list: 39 # print(row.id,row.content,row.user_info.name,row.parent_id) 40 comment_list = [ 41 {'id': 1, 'content': 'Python最牛逼', 'user': '搞基建', 'parent_id': None}, 42 {'id': 2, 'content': 'Java最牛逼', 'user': '搞基建', 'parent_id': None}, 43 {'id': 3, 'content': 'PHP最牛逼', 'user': '搞基建', 'parent_id': None}, 44 {'id': 4, 'content': '你最牛逼', 'user': '小比虎', 'parent_id': 1}, 45 {'id': 5, 'content': '老师最你比', 'user': '李欢', 'parent_id': 1}, 46 {'id': 6, 'content': '郭永昌是...', 'user': '郭永昌', 'parent_id': 4}, 47 {'id': 7, 'content': '哈哈我是流氓...', 'user': '崔月圆', 'parent_id': 2}, 48 {'id': 8, 'content': '我女朋友好漂亮...', 'user': '崔月圆', 'parent_id': 3}, 49 {'id': 9, 'content': '见到你女友,交定你朋友...', 'user': '搞基建', 'parent_id': 8}, 50 {'id': 10, 'content': '见到你女友,交定你朋友...', 'user': '鼻环', 'parent_id': None}, 51 ] 52 """ 53 comment_tree = Node.create_tree(comment_list) 54 for i in comment_tree: 55 print(i) 56 """ 57 # hash_comment_list = {} 58 # for m in range(len(comment_list)): 59 # comment_list[m].update({'children':[]}) 60 # hash_comment_list[comment_list[m]['id']] = comment_list[m] 61 # # print(hash_comment_list) 62 # ret = [] 63 # for i in range(len(comment_list)): 64 # node = comment_list[i] 65 # pnode = hash_comment_list.get(node['parent_id']) 66 # if pnode: 67 # pnode['children'].append(node) 68 # else: 69 # ret.append(node) 70 # print(ret) 71 72 # hash_comment_list = {} 73 # for item in comment_list: 74 # item.update({'children': []}) 75 # hash_comment_list[item['id']] = item 76 # # print(hash_comment_list) 77 # ret = [] 78 # for row in comment_list: 79 # node = row 80 # pnode = hash_comment_list.get(node['parent_id']) 81 # if pnode: 82 # pnode['children'].append(node) 83 # else: 84 # ret.append(node) 85 # print(comment_list) 86 # print(ret) 87 88 89 # for i in comment_list: 90 # i.update({'children': []}) 91 # 92 # for i in comment_list: 93 # if i['id'] == 5: 94 # i['children'].append(i) 95 # 96 # for i in comment_list: 97 # print(i) 98 99 """ 100 [ 101 { 102 'id': 1, 103 'content': 'Python最牛逼', 104 'user': '搞基建', 105 'parent_id': None, 106 'children': [ 107 {'id': 4, 'content': '你最牛逼', 'user': '小比虎', 'parent_id': 1, 'children': [ 108 {'id': 6, 'content': '郭永昌是...', 'user': '郭永昌', 'parent_id': 4, 'children': []}, 109 ]}, 110 {'id': 5, 'content': '老师最你比', 'user': '李欢', 'parent_id': 1, 'children': []}, 111 ] 112 }, 113 { 114 'id': 2, 115 'content': 'Python最牛逼', 116 'user': '搞基建', 117 'parent_id': None, 118 'children': [] 119 }, 120 { 121 'id': 3, 122 'content': 'Python最牛逼', 123 'user': '搞基建', 124 'parent_id': None, 125 'children': [] 126 }, 127 ] 128 """ 129 return HttpResponse('Comment')
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 .comment-box{ 8 margin-left: 20px; 9 } 10 </style> 11 </head> 12 <body> 13 <div class="item"> 14 <a news_id="19" class="com">评论</a> 15 <div class="comment-list"> 16 <div class="comment-box"> 17 <span>Py最牛</span> 18 <div></div> 19 </div> 20 <div class="comment-box"> 21 <span>搞基建</span> 22 <div class="comment-box"> 23 <span>小胡比</span> 24 </div> 25 <div class="comment-box"> 26 <span>玩得患</span> 27 </div> 28 </div> 29 </div> 30 </div> 31 <div class="item"> 32 <a news_id="18" class="com">评论</a> 33 </div> 34 <div class="item"> 35 <a news_id="17" class="com">评论</a> 36 </div> 37 38 <script src="/static/jquery-2.1.4.min.js"></script> 39 //JS递归显示评论内容 40 <script> 41 $(function () { 42 bindCommentEvent(); 43 }); 44 function bindCommentEvent() { 45 $('.com').click(function () { 46 var news_id = $(this).attr('news_id'); 47 var _this = $(this); 48 $.ajax({ 49 url: '/comment/', 50 type: 'GET', 51 data: {news_id: news_id}, 52 dataType: "html", 53 success:function (arg) { 54 //create_tree(arg, _this); 55 console.log(arg); 56 _this.after(arg); 57 } 58 }) 59 }) 60 } 61 62 function diGui(children_list){ 63 var html = ""; 64 $.each(children_list,function (ck,cv) { 65 var b = '<div class="comment-box"><span>'; 66 b+= cv.content + "</span>"; 67 b += diGui(cv.children); 68 b += "</div>"; 69 html += b; 70 }); 71 return html; 72 } 73 74 function create_tree(data,$this) { 75 var html = '<div class="comment-list">'; 76 $.each(data,function (k,v) { 77 var a = '<div class="comment-box"><span>'; 78 a+= v.content + "</span>"; 79 // 创建子评论 80 a += diGui(v.children); 81 a+= "</div>"; 82 html += a; 83 }); 84 html += "</div>"; 85 $this.after(html); 86 } 87 </script> 88 </body> 89 </html>
1 #__author: Administrator 2 #date: 2016/12/26 3 from django import template 4 from django.utils.safestring import mark_safe 5 #simple_tag递归显示评论内容 6 #路径:/app01/templatetags 7 register = template.Library() 8 9 def diGui(children_list): 10 html = "" 11 for cv in children_list: 12 b = '<div class="comment-box"><span>' 13 b += cv['content'] + "</span>" 14 b += diGui(cv['children']) 15 b += "</div>" 16 html += b 17 return html 18 19 @register.simple_tag 20 def create_tree(comment_list): 21 html = '<div class="comment-list">' 22 for v in comment_list: 23 a = '<div class="comment-box"><span>' 24 a += v['content'] + "</span>" 25 a += diGui(v['children']) 26 a += "</div>" 27 html += a 28 return mark_safe(html) 29 30 """ 31 function diGui(children_list){ 32 var html = ""; 33 $.each(children_list,function (ck,cv) { 34 var b = '<div class="comment-box"><span>'; 35 b+= cv.content + "</span>"; 36 b += diGui(cv.children); 37 b += "</div>"; 38 html += b; 39 }); 40 return html; 41 } 42 43 44 function create_tree(data,$this) { 45 var html = '<div class="comment-list">'; 46 $.each(data,function (k,v) { 47 var a = '<div class="comment-box"><span>'; 48 a+= v.content + "</span>"; 49 // 创建自评论 50 a += diGui(v.children); 51 a+= "</div>"; 52 html += a; 53 }); 54 55 html += "</div>"; 56 $this.after(html); 57 } 58 """
1 {% load laogao %} 2 {% create_tree comment_tree %}//simple_tag递归显示评论内容
1 from django.shortcuts import render 2 def test(request): 3 #获取请求头信息 4 #print(type(request)) 5 from django.core.handler.wsgi import WSGIRequest 6 print(request.environ.get('HTTP_USER_AGENT')) 7 return render(request,'test.html')
1 import smtplib 2 from email.mime.text import MIMEText 3 from email.utils import formataddr 4 5 def email(email_list, content, subject="抽屉新热榜-用户注册"): 6 msg = MIMEText(content, 'plain', 'utf-8') 7 msg['From'] = formataddr(["抽屉新热榜",'wptawy@126.com']) 8 msg['Subject'] = subject 9 # SMTP服务- 10 server = smtplib.SMTP("smtp.126.com", 25) #url 端口 11 server.login("wptawy@126.com", "JUEmimima") 12 server.sendmail('wptawy@126.com', email_list, msg.as_string()) 13 server.quit() 14 15 # email(['xiaohu@live.com','jinxin@live.com'], 'xiaohuzuishuai') 16 17 18 发送短信微信:从服务商处购买url,用如 19 http://www.fasong.com?...&...&... 20 21 也可用requests模块 import requests