zoukankan      html  css  js  c++  java
  • BBS

    一、文章评论

        <div class="comment_region">
            <div class="row">
                <div class="col-md-8">
                    <p>昵称:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"></p>
                    <p>评论内容:</p>
                    <textarea name="" id="comment-text" cols="63" rows="10"></textarea>
                    <button class="btn btn-default pull-right comment-btn">提交</button>
                </div>
            </div>
    
        </div>

    效果:

    事件:

    from django.db import transaction
    
    def comment(request):
        article_id = request.POST.get('article_id')
        content =request.POST.get('content')
        pid = request.POST.get('pid')
        user_id = request.user.pk
    
        res = {"state":True}
    
        with transaction.atomic():   # 事务 有关联
            if not pid: # 提交根评论
                obj = Comment.objects.create(user_id = user_id,article_id = article_id,content=content)
            else:  # 提交子评论
                obj = Comment.objects.create(user_id=user_id, article_id=article_id, content=content,parent_comment_id=pid)
    
            # comment_count 加 + 1
            Article.objects.filter(pk=article_id).update(comment_count=F("comment_count") + 1)
    
        res['time'] = obj.create_time.strftime('%Y-%m-%d %H:%M')
        res['content'] = obj.content
        if obj.parent_comment_id:
            res['pid'] = obj.parent_comment_id
            res['pidname'] = obj.parent_comment.user.username
        return JsonResponse(res)
    
    
    def get_comment_tree(request,article_id):
        ret = list(Comment.objects.filter(article_id=article_id).values('pk','content','parent_comment_id','user__username'))
        print(ret)
        return JsonResponse(ret,safe=False)
    path('comment/', views.comment),
    re_path(r'get_comment_tree/(d+)', views.get_comment_tree),
    comment_list = Comment.objects.filter(article_id=article_id)

    评论树  评论楼  提交评论事件:

    {% extends 'base.html' %}
    
    {% block content %}
    
        <h3 class="text-center">{{ article.title }}</h3>
        <div class="content">
            {{ article.articledetail.content|safe }}
        </div>
    
    
        <input type="hidden" id="hid_article_pk" value="{{ article.pk }}">
          <input type="hidden" id="hid_username" value="{{ request.user.username }}">
    
        <div id="div_digg">
            <div class="diggit digg">
                <span class="diggnum" id="digg_count">{{ article.up_count }}</span>
            </div>
            <div class="buryit digg">
                <span class="burynum" id="bury_count">{{ article.down_count }}</span>
            </div>
            <div id="digg_word" class="pull-right"></div>
        </div>
        <div class="clearfix"></div>
    
        <hr>
        <p>评论树</p>
        <div class="comment_tree">
    
            <script>
                (function () {
                    $.ajax({
                        url:'/blog/get_comment_tree/'+$('#hid_article_pk').val(),
                        success:function (comment_list) {
    
                            var comment_html = "";
                            $.each(comment_list,function (index,comment) {
                                var username = comment.user__username;
                                var content = comment.content;
                                var pk = comment.pk;
                                var pid = comment.parent_comment_id;
                                console.log(comment);
                                 s = '<div class="comment_tree_item" id="'+pk+'"><span>'+username+'</span><span>'+content+'</span> </div>'
    
                                 if(pid){
                                    $('#'+pid).append(s)
    
                                 }else{
                                     $('.comment_tree').append(s)
                                 }
                            })
                        }
                    })
                })()
    
            </script>
    
        </div>
    
        <hr>
        <p>评论楼</p>
        <ul class="list-group comment_list">
            {% for comment in comment_list %}
                <li class="list-group-item comment_item">
                    <div>
                        <a href="">#{{ forloop.counter }}楼</a>&nbsp;&nbsp;&nbsp;
                        <span>{{ comment.create_time|date:'Y-m-d H:i'}}</span>&nbsp;&nbsp;
                        <a href="">{{ comment.user.username  }}</a>
                        <a class="pull-right replay" pk = "{{ comment.pk }}" username="{{ comment.user.username }}">回复</a>
                    </div>
                    {% if comment.parent_comment_id %}
                        <div class="parent_comment_info well">
                            <a href="">@{{ comment.parent_comment.user.username }}</a>&nbsp;&nbsp;
                            <span>{{ comment.parent_comment.content }}</span>
                        </div>
                    {% endif %}
                    <div>
                        <p>{{ comment.content }}</p>
                    </div>
                </li>
            {% endfor %}
        </ul>
    
    
        <hr>
        <div class="comment_region">
            <div class="row">
                <div class="col-md-8">
                    <p>昵称:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"></p>
                    <p>评论内容:</p>
                    <textarea name="" id="comment-text" cols="63" rows="10"></textarea>
                    <button class="btn btn-default pull-right comment-btn">提交</button>
                </div>
            </div>
    
        </div>
    
    
    {% csrf_token %}
    
    <script src="/static/js/article_detail.js"></script>
    
        <script type="text/javascript">
    
            var pid = '';  // 空 为 根评论
    
            // 绑定 提交评论事件
            $('.comment-btn').click(function () {
    
                if("{{ request.user.username }}"){  // 登录 后操作
    
                    // val()   input select textarea 这三个可以 取 val()
                    var article_id = $('#hid_article_pk').val();
    
                    if($('#comment-text').val()[0] !== "@"){
                        pid = ""
                    }
    
                    //@alex
    567
                    // 获取 子评论 内容
                    if(pid){
                        var index = $('#comment-text').val().indexOf('
    ');
                        var content = $('#comment-text').val().slice(index+1)
                    }else{
                        var content = $('#comment-text').val();
                    }
    
                    $.ajax({
                        url:'/blog/comment/',
                        type:'post',
                        data:{
                            article_id:article_id,
                            content:content,
                            pid:pid,
                            csrfmiddlewaretoken:$('input[name="csrfmiddlewaretoken"]').val()
                        },
                        success:function (data) {
                            console.log(data);
                            if(data.state){  // 提交成功
                                console.log('-----------',data);
                                // 根评论 显示
                                var floor = $('.comment_list .comment_item').length+1;
                                var ctime = data.time;
                                var username = $('#hid_username').val();
                                var content =  data.content;
                                var pname = data.pidname;
                                if(data.pid){  // 子评论
                                     var s ='<li class="list-group-item comment_item"><div><a href="">#'+floor+'楼</a>&nbsp;&nbsp;&nbsp; <span>'+ ctime+ ' </span>&nbsp;&nbsp;<a href="">'+ username +'</a> </div> <div> ' +
                                         ' <div class="parent_comment_info well">
    ' +
                                         ' <a href="">@'+pname+'</a>&nbsp;&nbsp;
    ' +
                                         ' </div>'+
                                         '<p>'+content+'</p> </div> </li>';
                                }else{
                                     // 应该有 2 套 s
                                     var s ='<li class="list-group-item comment_item"><div><a href="">#'+floor+'楼</a>&nbsp;&nbsp;&nbsp; <span>'+ ctime+ ' </span>&nbsp;&nbsp;<a href="">'+ username +'</a> </div> <div> <p>'+content+'</p> </div> </li>';
                                }
    
                                $('.comment_list').append(s);
    
                                //清空数据
                                $('#comment-text').val("");
                                //清空pid
                                pid = "";
    
                            }
                        }
                    })
    
                }else{  // 未登录
                    location.href = "/login/"
                }
            });
    
            // 绑定回复 按钮事件
            $('.comment_item .replay').click(function () {
                // 获取焦点
                $('#comment-text').focus();
                var val ="@" + $(this).attr('username')+ '
    ';  // 回复得人得 名字
                $('#comment-text').val(val);
    
                pid = $(this).attr("pk")  // pid
            })
    
        </script>
    
    
    {% endblock content%}
    article_detail.html

    二、知识点

    文章评论:
    1.提交根评论
    2.显示根评论
    --- render显示
    --- ajax显示
    3.提交子评论
    4.显示子评论
    --- render显示
    --- ajax显示
    评论楼
    评论树
    1.
    comment_list = Comment.objects.filter(article_id=article_id)

    2.事务
    with transaction.atomic(): # 事务 数据统一 一致
    if not pid: # 提交根评论
    obj = Comment.objects.create(user_id = user_id,article_id = article_id,content=content)
    else: # 提交子评论
    obj = Comment.objects.create(user_id=user_id, article_id=article_id, content=content,parent_comment_id=pid)

    # comment_count 加 + 1
    Article.objects.filter(pk=article_id).update(comment_count=F("comment_count") + 1)

    3.a标签
    href = "url" 向外链接
    href = '#xxx' 向内定位 锚点
    不用#xxx,可以用获取焦点:$('#comment-text').focus();

    4.val()
    input select textarea 这三个可以 取 .val() 赋值 .val('')

    5.js得截取方法:(charAt indexOf slice)
    var s = "hello world";
    console.log(s.charAt(4)); // o 索引找字符
    console.log(s.indexOf('e')); // 1 字符找索引
    console.log(s.slice(1,4)); // ell 切片

    6.根评论 / 子评论 获取 content
    var pid = ''; // 空 为 根评论
    if($('#comment-text').val()[0] !== "@"){
    pid = ""
    }

    // 获取 子评论 内容 // @alex 567
    if(pid){
    var index = $('#comment-text').val().indexOf(' ');
    var content = $('#comment-text').val().slice(index+1)
    }else{
    var content = $('#comment-text').val();
    }

    7.两个bug:
    (1) 先提交子评论,在不刷新页面的情况下再提交根评论会怎样?
    //清空数据
    $('#comment-text').val("");
    //清空pid
    pid = "";
    (2) 先按回复按钮,然后将文本框中的"@..."手动去除,再点提交会怎样?
    if($('#comment-text').val() !== "@"){
    pid = ""
    }

    8.datatime.datetime
    时间对象,不能序列化! 字典 列表 可序列化, 对象不可序列化!!
    办法:
    res['time'] = obj.create_time.strftime('%Y-%m-%d %H:%M')
    return JsonResponse(res)
    补充:
    import datetime
    datetime.date
    datetime.time
    datetime.datetime
    datetime.timedelta(days=7)

    now = datetime.datetime.now() # 对象
    now.strftime('%Y-%m')
    now.strftime('%Y-%m-%d')
    now.strftime('%Y-%m-%d %X')
    now.strftime('%Y-%m-%d %H:%M')


    delta = datetime.timedelta(days=7)
    now + delta // 时间相加

    9.评论楼
    楼层:
    <a href="">#{{ forloop.counter }}楼</a>&nbsp;
    时间:
    <span>{{ comment.create_time|date:'Y-m-d H:i'}}</span>&nbsp;
    评论者:
    <a href="">{{ comment.user.username }}</a>
    回复:(pk username)
    <a class="pull-right replay" pk = "{{ comment.pk }}" username="{{ comment.user.username }}">回复</a>
    点击回复:
    // 绑定回复 按钮事件
    $('.comment_item .replay').click(function () {
    // 获取焦点
    $('#comment-text').focus();
    var val ="@" + $(this).attr('username')+ ' '; // 回复得人得 名字
    $('#comment-text').val(val);

    pid = $(this).attr("pk") // pid
    })
    判断是否有父评论:
    {% if comment.parent_comment_id %}
    <div class="parent_comment_info well">
    <a href="">@{{ comment.parent_comment.user.username }}</a>&nbsp;&nbsp;
    <span>{{ comment.parent_comment.content }}</span>
    </div>
    {% endif %}

    10.ajax显示评论:
    var floor = $('.comment_list .comment_item').length+1;
    var ctime = data.time; // 时间字符串 因为时间对象json传不过来。
    var username = $('#hid_username').val();
    var content = data.content; // content 应该从库里取,不应该直接拿前端得数据!因为前端得content是经过 过滤转义 特殊字符后才存到数据库中。
    var pname = data.pidname;
    if(data.pid){ // 子评论
    var s ='<li class="list-group-item comment_item"><div><a href="">#'+floor+'楼</a>&nbsp;&nbsp;&nbsp; ' +
    '<span>'+ ctime+ ' </span>&nbsp;&nbsp;<a href="">'+ username +'</a> </div> <div> ' +
    ' <div class="parent_comment_info well"> ' +
    ' <a href="">@'+pname+'</a>&nbsp;&nbsp; ' +
    ' </div><p>'+content+'</p> </div> </li>';
    }else{
    // 应该有 2 套 s
    var s ='<li class="list-group-item comment_item"><div><a href="">#'+floor+'楼</a>&nbsp;&nbsp;&nbsp;' +
    ' <span>'+ ctime+ ' </span>&nbsp;&nbsp;<a href="">'+ username +'</a> </div>' +
    ' <div> <p>'+content+'</p> </div> </li>';
    }

    $('.comment_list').append(s);

    11.评论树:
    样式:
    111
    444
    555
    222
    333

    方法:
    1.递归!! 麻烦!
    自己调自己
    有个结束条件
    2. comment_list 取出 pid
    前端拿到,所有数据
    先展示 所有得根评论
    子评论 append到某条根评论下

    <div pk=1>111
    <div pk=4>444
    <div pk=5>555</div>
    </div>
    </div>
    <div pk=2>222</div>
    <div pk=2>333</div>

    知识点:
    匿名函数,自执行!
    (function () {
    alert(111)
    })()

    应用: $.each(...)
    <div class="comment_tree">
    <script>
    (function () {
    $.ajax({
    url:'/blog/get_comment_tree/'+$('#hid_article_pk').val(),
    success:function (comment_list) {

    var comment_html = "";
    $.each(comment_list,function (index,comment) {
    var username = comment.user__username;
    var content = comment.content;
    var pk = comment.pk;
    var pid = comment.parent_comment_id;
    console.log(comment);
    var s = '<div class="comment_tree_item" id="'+pk+'"><span>'+username+'</span><span>'+content+'</span> </div>'

    if(pid){ // 子评论
    $('#'+pid).append(s)

    }else{ // 父评论
    $('.comment_tree').append(s)
    }
    })
    }
    })
    })()

    </script>
    </div>

    补充:
    最新评论指定放到前面: (prepend)
    jquery 文档操作:
    append appendTo
    prepend prependTo
    before insertBefore
    after insertAfter
    clone
    replaceWith replaceAll
    empty remove detach

    样式缩进:
    .comment_tree_item{
    margin-left: 20px;
    }

    后台:
    def get_comment_tree(request,article_id):
    ret = list(Comment.objects.filter(article_id=article_id).values('pk','content','parent_comment_id','user__username'))
    print(ret)
    return JsonResponse(ret,safe=False)

    注意点:
    queryset 对象没法做 序列化
    办法:
    list(quertset) # 强转
    BUT:
    return JsonResponse(ret)
    条件:
    In order to allow non-dict objects to be serialized set the safe parameter to False.
    修改:
    return JsonResponse(ret,safe=False)

     

  • 相关阅读:
    开发环境之Webpack
    开发环境之Nginx
    Winfrom排坑
    Winfrom打包教程(Inno Setup工具)
    博客园美化教程
    开发环境之Tomcat
    IDEA编码时卡顿问题
    学习Spring5源码时所遇到的坑
    docker+jmeter+influx+granfana搭建性能测试监控平台
    Windows10上安装 WSL---Ubuntu
  • 原文地址:https://www.cnblogs.com/alice-bj/p/9150858.html
Copyright © 2011-2022 走看看