项目知识补充--评论楼-注册图片预览
创建评论楼 两个方式 一 后台写标签 传入到前端 二 直接js直接在前端生成
一、后端生成代码
def detail(request,site,nid): """ 详细内容 :param request: :param site: :param nid: :return: """ # print("......") if request.method == "GET": blog=models.Blog.objects.filter(site=site).first() tag_list=models.Article2Tag.objects.filter(tag__blog=blog).values("tag_id","tag__title").annotate(c=Count("id")) category_list=models.Article.objects.filter(blog=blog).values("category_id","category__title").annotate(c=Count("nid")) date_list = models.Article.objects.filter(blog=blog).extra( select={"c": "strftime('%%Y-%%m',create_time)"}).values("c").annotate(ct=Count("nid")) article_list=models.Article.objects.filter(blog=blog,nid=nid).values("title","nid","up_count","down_count","category__title","articledetail__content").first() comment_list = models.Comment.objects.filter(article_id=nid).values("nid","reply_id","user__nid","user__nickname","create_time","content","reply__user__nickname") print(comment_list) comment_list_dict={} #生成一个空字典 for item in comment_list: #从数据库获取的评论数进行遍历 item['child'] = [] #创建一个孩子的下的空列表 comment_list_dict[item['nid']] = item #字典的key=item字段 print(comment_list_dict) result = [] for item in comment_list: pid = item['reply_id'] #回复者 if pid: # 如果pid为True comment_list_dict[pid]['child'].append(item) else: # 为None result.append(item) # result结果增加item from utils.comment import comment_tree comment_str = comment_tree(result) return render(request,'detail.html',{ "blog":blog, "tag_list":tag_list, "category_list":category_list, "date_list":date_list, "row":article_list, "comment_str":comment_str })
def comment_tree(comment_list): """ :param comment_list: :return: """ comment_str="<div class='comment'>" for row in comment_list: tpl="<div class='content'>%s发布:%s%s</div><div class='content'>%s</div>"%(row['user__nickname'],row['create_time'],row['reply__user__nickname'],row['content']) comment_str +=tpl if row['child']: child_str=comment_tree(row['child']) comment_str +=child_str comment_str +="</div>" return comment_str
<div> <span>发表评论:</span> {{ comment_str|safe }} </div>
二 js方法
url(r'^comment-(?P<nid>\d+)/',views.comment),
import json from datetime import date from datetime import datetime class JsonCustomEncoder(json.JSONEncoder): def default(self, field): if isinstance(field, datetime): return field.strftime('%Y-%m-%d %H:%M:%S') elif isinstance(field, date): return field.strftime('%Y-%m-%d') else: return json.JSONEncoder.default(self, field) def comment(request,nid): response={'status':True,'data':None,'msg':None} """ 文章评论 :param request: :return: """ # content=request.POST.get('content') # user=request.POST.get("user") # user = models.UserInfo.objects.filter(username=user).first() # article_id = request.POST.get('article_id') # print(content,user.nid,article_id) # models.Comment.objects.create(content=content,article_id=article_id,user_id=user.nid) # try: comment_list = models.Comment.objects.filter(article_id=nid).values("nid", "reply_id", "user__nid", "user__nickname", "create_time", "content", "reply__user__nickname") comment_list_dict = {} # 生成一个空字典 for item in comment_list: # 从数据库获取的评论数进行遍历 item['child'] = [] # 创建一个孩子的下的空列表 comment_list_dict[item['nid']] = item # 字典的key=item字段 print(comment_list_dict) result = [] for item in comment_list: pid = item['reply_id'] # 回复者 if pid: # 如果pid为True comment_list_dict[pid]['child'].append(item) else: # 为None result.append(item) # result结果增加item response['data']=result # except Exception as e: # response['status'] = False # response['msg']=str(e) # ds = json.dumps(d, cls=JsonCustomEncoder) return HttpResponse(json.dumps(response,cls=JsonCustomEncoder))
<span>发表评论:</span> {# {{ comment_str|safe }}#} <div id="commentArea"> <script src="/static/jquery-3.2.1.js"></script> <script> /* 1.调用对象方式时,通过调用类的prototype中的方法,可以扩展 2.正则表达式 /\w+/g 3.字符串replace替换 */ String.prototype.Format =function (arg) { /* 字符串格式化,this,当前字符串 arg,Format方法传入的参数 return,格式化之后获取的新内容 前端写正则表达式 用(//)表示 g代表全局变量 */ var temp =this.replace(/\{(\w+)\}/g,function (k,kk) { return arg[kk]; }); return temp; }; $(function () { //发送ajax请求,获取所有评论信息 //列表 //js生成结构 $.ajax({ url:'/comment-{{ row.nid }}/', type:'GET', dataType:"JSON", success:function (arg) { if(arg.status){ console.log(arg.data); var comment=commenTree(arg.data); console.log(comment); $('#commentArea').append(comment); }else{ alert(arg.msg); } } }) }); function commenTree(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.lenth>0){ comment_str +=commenTree(row.child); } }); comment_str += '</div>'; return comment_str; }
---恢复内容结束---
一、本地图片上传预览
1. 上传文件框隐藏到图片上面,点击图片相当于点上传文件框
<div class="login"> <div style="position: relative;height:80px;width: 80px; left:260px;top: -10px "> <img id="previewImg" style="height:80px;width: 80px;" src="/static/image/default.png"> <input style="height: 80px;width: 80px; position: absolute; top:0;left: 0; opacity: 0" type="file"> {{ obj.avatar }} </div> </div>
2. Ajax 上传并预览
#获取到头像,通过原生Ajax传到后端,后端返回一个路径,重新给image 的src赋值路径 #问题: 用户上传完头像,但没有注册,会在硬盘里出现多余的头像 # 有些网站是先上传到临时目录,注册完再移动到新的目录
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap-3.3.5-dist/css/bootstrap.css" /> <style> .login{ width: 600px; margin: 0 auto; padding: 20px; margin-top: 80px; } .f1{ position: absolute;height:80px;width: 80px;top:0;left: 0;opacity: 0; } </style> </head> <body> <div class="login"> <div style="position: relative;height:80px;width: 80px; left:260px;top: -10px "> <img id="previewImg" style="height:80px;width: 80px;" src="/static/image/default.png"> <input id="imgSelect" style="height: 80px;width: 80px; position: absolute; top:0;left: 0; opacity: 0" type="file"> {{ obj.avatar }} </div> </div> <script src="/static/jquery-3.2.1.js"></script> <script> $(function () { bindAvartar1(); }); function bindAvartar1() { $("#imgSelect").change(function () { //$(this)[0] #jquery变成DOM对象 //$(this)[0].files #获取上传当前文件的上传对象 //$(this)[0].files[0] #获取上传当前文件的上传对象的某个对象 var obj = $(this)[0].files[0]; console.log(obj); //ajax 发送后台获取头像路径 //img src 重新定义新的路径 var formdata = new FormData(); //创建一个对象 formdata.append("file",obj); var xhr = new XMLHttpRequest(); xhr.open("POST","/register/"); xhr.send(formdata); xhr.onreadystatechange = function () { if(xhr.readyState ==4){ var file_path = xhr.responseText; console.log(file_path); $("#previewImg").attr("src","/" + file_path) } }; }) } </script> </body> </html>
import os def register(request): if request.method == "GET": return render(request,"register.html") else: print(request.POST) print(request.FILES) file_obj = request.FILES.get("file") print(file_obj) file_path = os.path.join("static", file_obj.name) with open(file_path, "wb") as f: for chunk in file_obj.chunks(): f.write(chunk) return HttpResponse(file_path)
3. 本地上传并预览两种方式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap-3.3.5-dist/css/bootstrap.css" /> <style> .login{ width: 600px; margin: 0 auto; padding: 20px; margin-top: 80px; } .f1{ position: absolute;height:80px;width: 80px;top:0;left: 0;opacity: 0; } </style> </head> <body> <div class="login"> <div style="position: relative;height:80px;width: 80px; left:260px;top: -10px "> <img id="previewImg" style="height:80px;width: 80px;" src="/static/image/default.png"> <input id="imgSelect" style="height: 80px;width: 80px; position: absolute; top:0;left: 0; opacity: 0" type="file"> {{ obj.avatar }} </div> </div> <script src="/static/jquery-3.2.1.js"></script> <script> $(function () { bindAvartar2(); }); function bindAvartar2() { $("#imgSelect").change(function () { var obj = $(this)[0].files[0]; console.log(obj); //将文件对象上传到浏览器 //IE10 以下不支持 var v = window.URL.createObjectURL(obj); $("#previewImg").attr("src",v); //不会自动释放内存 //当加载完图片后,释放内存 document.getElementById("previewImg").onload= function () { window.URL.revokeObjectURL(v); }; }) } function bindAvartar3() { $("#imgSelect").change(function () { var obj = $(this)[0].files[0]; console.log(obj); var reader = new FileReader(); reader.onload = function (e) { $("#previewImg").attr("src",this.result); }; reader.readAsDataURL(obj) }) } </script> </body> </html>
4.以后用法
#先用本地预览,如果不支持,使用第三种方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap-3.3.5-dist/css/bootstrap.css" /> <style> .login{ width: 600px; margin: 0 auto; padding: 20px; margin-top: 80px; } .f1{ position: absolute;height:80px;width: 80px;top:0;left: 0;opacity: 0; } </style> </head> <body> <div class="login"> <div style="position: relative;height:80px;width: 80px; left:260px;top: -10px "> <img id="previewImg" style="height:80px;width: 80px;" src="/static/image/default.png"> <input id="imgSelect" style="height: 80px;width: 80px; position: absolute; top:0;left: 0; opacity: 0" type="file"> </div> </div> <script src="/static/jquery-3.2.1.js"></script> <script> $(function(){ bindAvatar(); }); function bindAvatar(){ if(window.URL.createObjectURL){ bindAvatar2(); }else if(window.FileReader){ bindAvatar3() }else{ bindAvatar1(); } } function bindAvatar1() { $("#imgSelect").change(function () { //$(this)[0] #jquery变成DOM对象 //$(this)[0].files #获取上传当前文件的上传对象 //$(this)[0].files[0] #获取上传当前文件的上传对象的某个对象 var obj = $(this)[0].files[0]; console.log(obj); //ajax 发送后台获取头像路径 //img src 重新定义新的路径 var formdata = new FormData(); //创建一个对象 formdata.append("file",obj); var xhr = new XMLHttpRequest(); xhr.open("POST","/register/"); xhr.send(formdata); xhr.onreadystatechange = function () { if(xhr.readyState ==4){ var file_path = xhr.responseText; {# console.log(file_path);#} $("#previewImg").attr("src","/" + file_path) } }; }) } function bindAvatar2() { $("#imgSelect").change(function () { var obj = $(this)[0].files[0]; console.log(obj); //将文件对象上传到浏览器 //IE10 以下不支持 //不会自动释放内存 //当加载完图片后,释放内存 document.getElementById("previewImg").onload= function () { window.URL.revokeObjectURL(v); }; var v = window.URL.createObjectURL(obj); $("#previewImg").attr("src",v); }) } function bindAvatar3() { $("#imgSelect").change(function () { var obj = $(this)[0].files[0]; console.log(obj); var reader = new FileReader(); reader.onload = function (e) { $("#previewImg").attr("src",this.result); }; reader.readAsDataURL(obj) }) } </script> </body> </html>