• 项目知识补充--评论楼-注册图片预览


    创建评论楼 两个方式
    一 后台写标签 传入到前端
    二 直接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
            })
    View.py
    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
    comment.py
     <div>
     <span>发表评论:</span>
    
      {{ comment_str|safe }}
    
    </div>
    html

    二 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))
    View.py
      <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;
            }
    detail.html

    ---恢复内容结束---

    一、本地图片上传预览

     1. 上传文件框隐藏到图片上面,点击图片相当于点上传文件框

    <div class="login">
        <div style="position: relative;height:80px; 80px; left:260px;top: -10px ">
            <img id="previewImg" style="height:80px; 80px;" src="/static/image/default.png">
            <input  style="height: 80px; 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{
                 600px;
                margin: 0 auto;
                padding: 20px;
                margin-top: 80px;
            }
            .f1{
                position: absolute;height:80px; 80px;top:0;left: 0;opacity: 0;
            }
    
        </style>
    </head>
    <body>
        <div class="login">
            <div style="position: relative;height:80px; 80px; left:260px;top: -10px ">
                <img id="previewImg" style="height:80px; 80px;" src="/static/image/default.png">
                <input id="imgSelect" style="height: 80px; 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>
    register.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)
    View.py

    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{
                 600px;
                margin: 0 auto;
                padding: 20px;
                margin-top: 80px;
            }
            .f1{
                position: absolute;height:80px; 80px;top:0;left: 0;opacity: 0;
            }
    
        </style>
    </head>
    <body>
        <div class="login">
            <div style="position: relative;height:80px; 80px; left:260px;top: -10px ">
                <img id="previewImg" style="height:80px; 80px;" src="/static/image/default.png">
                <input id="imgSelect" style="height: 80px; 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>
    View Code

    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{
                 600px;
                margin: 0 auto;
                padding: 20px;
                margin-top: 80px;
            }
            .f1{
                position: absolute;height:80px; 80px;top:0;left: 0;opacity: 0;
            }
    
        </style>
    </head>
    <body>
        <div class="login">
            <div style="position: relative;height:80px; 80px; left:260px;top: -10px ">
                <img id="previewImg" style="height:80px; 80px;" src="/static/image/default.png">
                <input id="imgSelect" style="height: 80px; 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>
    View Code
  • 相关阅读:
    call、apply、bind函数的理解以及手写。
    父div里两个子div(inline-block),为什么两个子div中间会有小缝隙,如何解决?
    手写柯里化
    arguments的理解
    New
    BFC
    useCallBack和useMemo的用法
    观察者模式和发布订阅模式
    grid布局
    Android常见输入法的包名和主类名
  • 原文地址:https://www.cnblogs.com/niejinmei/p/7212418.html
Copyright © 2020-2023  润新知