评论显示与追加

评论的显示

1.数据库设计:(创建一个评论表)
class Comments(Base):
    """
    """
    content = models.TextField(verbose_name="内容", help_text="内容")

    author = models.ForeignKey('user.Users', on_delete=models.SET_NULL, null=True)
    news = models.ForeignKey('News', on_delete=models.CASCADE)
    pareent=models.ForeignKey('self',on_delete=models.CASCADE,null=True,blank=True)#关联父级关联

    class Meta:
        ordering = ['-update_time', '-id']
        db_table = "tb_comments"  # 指明数据库表名
        verbose_name = "评论"  # 在admin站点中显示的名称
        verbose_name_plural = verbose_name  # 显示的复数名称

    def __str__(self):
        return '<评论{}>'.format(self.id)
#将数据序列化输出
    def to_dict(self):
        comm_dict={
            'news_id':self.news_id,
            'content_id':self.id,
            'content':self.content,
            'update_tiem':self.update_time.strftime('%Y年%m月%d日 %H:%M'),
            'author':self.author.username ,
            'pareent':self.pareent.to_dict() if self.pareent else None,
        }
        return comm_dict;

2.在视图函数中写相应的代码,因为评论和新闻详情在一块,所以评论应该放在新闻详情这一块中

class New_detail(View):
    def get(self,request,news_id):
        #获取数据
        new= News.objects.select_related('tag', 'author').only('title', 'content', 'update_time', 'tag__name',
                                                               'author__username').filter(delete_is=False, id=news_id).first()
        #获取数据
        comments=Comments.objects.select_related('author','pareent').only('author__username','update_time','content',
                                                                'pareent__update_time').filter(delete_is=False,id=news_id)
        comment_list=[];
        for c in comments:
            comment_list.append(c.to_dict())
        if new:
            # return render(request,'news/news_detail.html',context={'news':new})
            return  render(request,'news/news_detail.html',locals())

        else:
            return HttpResponseNotFound('<h1>页面不存在</h1>')

前端页面的书写:

{% extends 'base/base.html' %}
{% block title %}文章详情页{% endblock %}
{% block link %}
      <link rel="stylesheet" href="../../static/css/news/news-detail.css">
{% endblock %}

{% block main_contain %}
    <div class="main-contain">

    <div class="news-contain">
      <h1 class="news-title">{{ new.title }}</h1>
      <div class="news-info">
        <div class="news-info-left">
          <span class="news-author">{{ new.author.username }}</span>
          <span class="news-pub-time">{{ new.update_time }}</span>
          <span class="news-type">{{ new.tag.name }}</span>
        </div>
      </div>
      <article class="news-content">
        {{ new.content | safe}}
      </article>
          <div class="comment-contain">
        <div class="comment-pub clearfix">
          <div class="new-comment">
            文章评论(<span class="comment-count">0</span>)
          </div>
          {% if user.is_authenticated %}
          <div class="comment-control logged-comment" news-id="{{ news.id }}">
            <input type="text" placeholder="请填写评论">
            <button class="comment-btn">发表评论</button>
          </div>
        {% else %}
          <div class="comment-control please-login-comment" news-id="{{ news.id }}">
            <input type="text" placeholder="请登录后参加评论" readonly>
            <button class="comment-btn">发表评论</button>
          </div>
        {% endif %}

        </div>
        <ul class="comment-list">
          {% for one_comment in comment_list %}
            <li class="comment-item">
            <div class="comment-info clearfix">
              <img src="{% static 'images/avatar.jpeg' %}" alt="avatar" class="comment-avatar">
              <span class="comment-user">{{ one_comment.author }}</span>
              <!--<span class="comment-pub-time">{{ one_comment.update_time }}</span>-->
            </div>
            <div class="comment-content">{{ one_comment.content }}</div>

              {% if one_comment.pareent %}
              <div class="parent_comment_text">
                <div class="parent_username">{{ one_comment.pareent.author }}</div>
                <br/>
                <div class="parent_content_text">
                  {{ one_comment.pareent.content }}
                </div>
              </div>
              {% endif %}

              <div class="comment_time left_float">{{ one_comment.update_time }}</div>
              <a href="javascript:void(0);" class="reply_a_tag right_float">回复</a>
              <form class="reply_form left_float" comment-id="{{ one_comment.content_id }}"
                    news-id="{{ one_comment.news_id }}">
                <textarea class="reply_input"></textarea>
                <input type="button" value="回复" class="reply_btn right_float">
                <input type="reset" name="" value="取消" class="reply_cancel right_float">
              </form>
          </li>
          {% endfor %}

        </ul>
      </div>

    </div>
</div>

{% endblock %}

{% block script %}
{% endblock %}

评论追加

1.js编写(难点)
$(function () {
  // 未登录提示框
  let $loginComment = $('.please-login-comment input');
  let $send_comment = $('.logged-comment .comment-btn');

  $('.comment-list').delegate('a,input', 'click', function () {

    let sClassValue = $(this).prop('class');

    if (sClassValue.indexOf('reply_a_tag') >= 0) {
      $(this).next().toggle();
    }

    if (sClassValue.indexOf('reply_cancel') >= 0) {
      $(this).parent().toggle();
    }

    if (sClassValue.indexOf('reply_btn') >= 0) {
      // 获取新闻id、评论id、评论内容
      let $this = $(this);
      let news_id = $this.parent().attr('news-id');
      let parent_id = $this.parent().attr('comment-id');
      let content = $this.prev().val();

      if (!content) {
        message.showError('请输入评论内容!');
        return
      }
      // 定义发给后端的参数
      let sDataParams = {
        "content": content,
        "pareent_id": parent_id
      };
      $.ajax({
        url: "/news/"+news_id+"/comments/",
        type: "POST",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify(sDataParams),
        dataType: "json",
      })
        .done(function (res) {
          if (res.errno === "0") {
            let one_comment = res.data;
            let html_comment = ``;
            html_comment += `
          <li class="comment-item">
            <div class="comment-info clearfix">
              <img src="/static/images/avatar.jpeg" alt="avatar" class="comment-avatar">
              <span class="comment-user">${one_comment.author}</span>
            </div>
            <div class="comment-content">${one_comment.content}</div>

                <div class="parent_comment_text">
                  <div class="parent_username">${one_comment.parent.author}</div>
                  <br/>
                  <div class="parent_content_text">
                    ${one_comment.parent.content}
                  </div>
                </div>

              <div class="comment_time left_float">${one_comment.update_time}</div>
              <a href="javascript:;" class="reply_a_tag right_float">回复</a>
              <form class="reply_form left_float" comment-id="${one_comment.content_id}" news-id="${one_comment.news_id}">
                <textarea class="reply_input"></textarea>
                <input type="button" value="回复" class="reply_btn right_float">
                <input type="reset" name="" value="取消" class="reply_cancel right_float">
              </form>

          </li>`;

            $(".comment-list").prepend(html_comment);
            $this.prev().val('');   // 请空输入框
            $this.parent().hide();  // 关闭评论框

          } else if (res.errno === "4101") {
            // 用户未登录
            message.showError(res.errmsg);
            setTimeout(function () {
              // 重定向到打开登录页面
              window.location.href = "/user/login/";
            }, 800)

          } else {
            // 失败,打印错误信息
            message.showError(res.errmsg);
          }
        })
        .fail(function () {
          message.showError('服务器超时,请重试!');
        });

    }
  });


  // 点击评论框,重定向到用户登录页面
  $loginComment.click(function () {

    $.ajax({
      url: "/news/" + $(".please-login-comment").attr('news-id') + "/comments/",
      type: "POST",
      contentType: "application/json; charset=utf-8",
      dataType: "json",
    })
      .done(function (res) {
        if (res.errno === "4101") {
          message.showError("请登录之后再评论!");
          setTimeout(function () {
            // 重定向到打开登录页面
            window.location.href = "/user/login/";
          }, 800)

        } else {
          // 失败,打印错误信息
          message.showError(res.errmsg);
        }
      })
      .fail(function () {
        message.showError('服务器超时,请重试!');
      });
  });

  // 发表评论
  $send_comment.click(function () {
    // 获取新闻id、评论id、评论内容
    let $this = $(this);
    let news_id = $this.parent().attr('news-id');
    // let parent_id = $this.parent().attr('comment-id');
    let content = $this.prev().val();

    if (!content) {
      message.showError('请输入评论内容!');
      return
    }
    // 定义发给后端的参数
    let sDataParams = {
      "content": content
    };
    $.ajax({
      url: "/news/"+news_id+"/comments/",
      type: "POST",
      contentType: "application/json; charset=utf-8",
      data: JSON.stringify(sDataParams),
      dataType: "json",
    })
      .done(function (res) {
        if (res.errno === "0") {
          let one_comment = res.data;
          let html_comment = ``;
          html_comment += `
          <li class="comment-item">
            <div class="comment-info clearfix">
              <img src="/static/images/avatar.jpeg" alt="avatar" class="comment-avatar">
              <span class="comment-user">${one_comment.author}</span>
            </div>
            <div class="comment-content">${one_comment.content}</div>

              <div class="comment_time left_float">${one_comment.update_time}</div>
              <a href="javascript:;" class="reply_a_tag right_float">回复</a>
              <form class="reply_form left_float" comment-id="${one_comment.content_id}" news-id="${one_comment.news_id}">
                <textarea class="reply_input"></textarea>
                <input type="button" value="回复" class="reply_btn right_float">
                <input type="reset" name="" value="取消" class="reply_cancel right_float">
              </form>

          </li>`;

          $(".comment-list").prepend(html_comment);
          $this.prev().val('');   // 请空输入框
          // $this.parent().hide();  // 关闭评论框

        } else if (res.errno === "4101") {
          // 用户未登录
          message.showError(res.errmsg);
          setTimeout(function () {
            // 重定向到打开登录页面
            window.location.href = "/user/login/";
          }, 800)

        } else {
          // 失败,打印错误信息
          message.showError(res.errmsg);
        }
      })
      .fail(function () {
        message.showError('服务器超时,请重试!');
      });
  });

  // get cookie using jQuery
  function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
      let cookies = document.cookie.split(';');
      for (let i = 0; i < cookies.length; i++) {
        let cookie = jQuery.trim(cookies[i]);
        // Does this cookie string begin with the name we want?
        if (cookie.substring(0, name.length + 1) === (name + '=')) {
          cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
          break;
        }
      }
    }
    return cookieValue;
  }

  function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
  }

  // Setting the token on the AJAX request
  $.ajaxSetup({
    beforeSend: function (xhr, settings) {
      if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
        xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
      }
    }
  });
});

相应的视图函数编写:
class CommentView(View):
    def post(self,request,news_id):
        if not request.user.is_authenticated:#判断是否有用户登录
            return to_json_data(errno=Code.SESSIONERR,errmsg="用户没有登录,请登录再评论")
        if not News.objects.only('id').filter(delete_is=False,id=news_id).exists():#判断是否有相应的新闻
            return to_json_data(errno=Code.PARAMERR, errmsg='新闻不存在!')
        #获取参数
        json_data=request.body;#获取前端传过来的参数
        if not json_data:
            return to_json_data(errno=Code.PARAMERR, errmsg='传输的值有误!')
        dict_data=json.loads(json_data);#j将闯过来的字符串类型的数据转换成字典类型
        content=dict_data.get('content');#获取输入的评论内容
        if not content:
            return to_json_data(errno=Code.PARAMERR, errmsg='评论内容不能为空!')
        # 回复评论 ---  二级评论
        parent_id = dict_data.get('pareent_id')
        try:
            if parent_id:
                if not Comments.objects.only('id').filter(is_delete=False, id=parent_id, news_id=news_id).exists():
                    return to_json_data(errno=Code.PARAMERR, errmsg='评论内容不能为空!');
        except Exception as e:
            logging.info('前台传的parent_id 异常:\n{}'.format(e))
            return to_json_data(errno=Code.PARAMERR, errmsg='未知异常')

            # 保存数据库
        news_content = Comments()
        news_content.content = content
        news_content.news_id = news_id
        news_content.author = request.user
        news_content.pareent_id = parent_id if parent_id else None
        news_content.save()
        return to_json_data(data=news_content.to_dict())

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值