郑统京 发表于 2022-10-28 00:01:33

BBS子评论功能实现

>前端代码HTML部分{#    评论楼开始#}
    <div>
    <ul class="list-group">
      {% for comment in comment_list %}
            <li class="list-group-item">
            <span>#{{ forloop.counter }}楼</span>
            <span>{{ comment.comment_time|date:'Y-m-d h:i:s' }}</span>
            <span>{{ comment.user.username }}</span>
            <span><a class="pull-right reply" username="{{ comment.user.username }}" comment_id="{{ comment.pk }}">回复</a></span>
            <div>
{#                判断当前评论是否是子评论 如果是则需要渲染对应的评论人名#}
                {% if comment.parent_id %}
                  <p>@{{ comment.parent.user.username }}</p>
                {% endif %}
                {{ comment.content }}
            </div>
            </li>
      {% endfor %}
    </ul>
    </div>
{#    评论楼结束#}JS部分// 设置一个全局标志位置
    let parentId =null
// 用户点击评论朝后端发送ajax请求
    $('#id_submit').click(function (){
      // 获取用户评论的内容
      let conTent=$('#id_comment').val()
      // 判断是否是子评论,如果是则需要手动将@username名字去除掉
      if(parentId){
            // 先找到\n对应的索引 然后利用切片 但是切片是顾头不顾尾 索引索引+1
            let indexNum = conTent.indexOf('\n') +1 ;
            conTent=conTent.slice(indexNum) // 将indexNum所有的数据切除,只保留后面的部分
      }
      $.ajax({
            url: '/comment/',
            type: 'post',
            data:{
                'article_id': '{{ article_obj.pk }}',
                // 如果后端没有值 那么就是null 后端存储null没有任何关系
                'parent_id':parentId,
                'content':conTent,
                'csrfmiddlewaretoken':'{{csrf_token}}'
            },
            success:function (args){
                if(args.code==1000){
                  $('#errors').text(args.msg)

                  // 将评论区里面的内容清空
                  $('#id_comment').val('')

                  // 临时渲染评论楼
                  let userName = '{{ request.user.username }}'
                  let temp = `
                  <li class="list-group-item">
                        <span>${userName}</span>
                        <span><a href="#" class="pull-right">回复</a></span>
                        <div>
                            ${conTent}
                        </div>
                  </li> `
                  // 将生成好的标签加到到评论楼里面去
                  $('.list-group').append(temp);
                  // 要清空全局的parentId字段
                  parentId =null

                }
            }
      })
    })

// 用户进行子评论
    $('.reply').click(function (){
      // 用户名字和评论id
      let commentUserName =$(this).attr('username')
      parentId =$(this).attr('comment_id')
      // 跳转到textarea中,把@+作者名字+换行添加进去
      $('#id_comment').val('@'+commentUserName+'\n').focus()
    })================================================================后端代码if request.user.is_authenticated():
    article_id = request.POST.get('article_id')
    content = request.POST.get('content')
    parentId = request.POST.get('parent_id')
    # 直接操作评论表存储数据
    with transaction.atomic():
      models.Article.objects.filter(pk=article_id).update(comment_num=F('comment_num')+1)
      models.Comment.objects.create(user=request.user,content=content,article_id=article_id,parent_id=parentId)=============================================================【思路整理】子评论的所有所及基本全部集中在前端JS和HTML代码中点击回复按钮发生了几件事
    1、评论框自动聚焦
    2、将回复按钮所在的那一行评论人的姓名进行拼接
    3、自动换行
1、首先在回复的标签中,创建一个点击事件,我们设置自己设置一个类为 class=‘reply’方便查找,为什么在这里不直接设置id呢,因为这个实在for循环里面的,可能会有多个相同id存在,就不合符id唯一的特性了,用类比较符合规范,见明字意
2、我们要进行子评论的时候要拿到跟评论的id和评论人的姓名,





















页: [1]
查看完整版本: BBS子评论功能实现