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

创建评论楼 两个方式
一 后台写标签 传入到前端
二 直接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
原文地址:https://www.cnblogs.com/niejinmei/p/7212418.html