评论系统

本文分析了一个评论系统的实现,包括前端获取文章id、用户id和评论内容,以及后端处理评论数据的逻辑。前端涉及字符串操作、遍历列表及设置属性,后端涉及获取文章和用户信息、保存评论到数据库以及构建评论树。
摘要由CSDN通过智能技术生成

项目分析

如果想评论一个文章,要拿到什么数据:
1.文章id
2.用户id
3.评论内容
4.父评论id(子评论)

1.文章的id通过个人主页的a标签拿到<a href="{{ foo.user.username }}/article/{{ foo.pk }}">{{ foo.title }}</a>,url为url(r"^(\w+)/(\w+)/article/(\d+)/$", views.article_detail),,最后把pk传递给显示文章详情的视图def article_detail(request, username, username1, pk):
2.用户通过user = models.UserInfo.objects.filter(username=username).first()拿到
3.评论内容通过前端发送ajax传递
4.父评论id,通过pid = $(this).attr("comment_pk");,在点击的回复按钮中定义一个属性拿到.

前端

技术点:
前端截取字符串的操作和each遍历列表
标签内设置属性以及拿到标签内属性

{% extends 'base.html' %}

{% block page-main %}
    <div class="article-detail">
        <h1>{{ article.title }}</h1>
        <p>{{ article.articledetail.content | safe }}</p>
    </div>
    <div>
        <div style="margin-top: 50px;margin-left: 500px; " class="action">
            <span class="glyphicon glyphicon-thumbs-up action1" id="digg_count">{{ article.up_count }}</span>

            <span class="glyphicon glyphicon-thumbs-down less action1"
                  id="bury_count">{{ article.down_count }}</span>
        </div>
    </div>
    <div id="error" style="color: red;"></div>

    <p>评论树</p>
    <div class="comment_tree">

    </div>
    <hr>
    <p>评论列表</p>
    <ul class="comment_list">
        {% for comment in comment_list %}
            <li class="list-group-item">
                <div>
                    <a href="">#{{ forloop.counter }}楼</a>&nbsp;&nbsp;
                    <span style="color: gray;">{{ comment.create_time|date:"Y-m-d" }}</span>&nbsp;&nbsp;
                    <span>{{ comment.user.username }}</span>
                    <a class="pull-right reply_btn" username="{{ comment.user.username }}"
                       comment_pk="{{ comment.pk }}"><span>回复</span></a>
                </div>

                {% if comment.parent_comment_id %}
                    <div class="pid_info">
                        <p>{{ comment.parent_comment.user.username }}&nbsp;&nbsp;&nbsp;{{ comment.parent_comment.content }}</p>
                    </div>
                {% endif %}

                <div class="con">
                    <p>
                        {{ comment.content }}
                    </p>
                </div>

            </li>
        {% endfor %}

    </ul>

    <div class="div_comment">
        <p>
            昵称<input type="text" id="tbCommentAuthor" disabled="disabled" class="author" size="50"
                     value="{{ request.user.username }}">
        </p>
        <p>
            评论:
        </p>
        <textarea name="" id="comment_content" cols="50" rows="10"></textarea>
        <button id="comment_btn">提交评论</button>
    </div>

    <div class="clear"></div>
    <div class="info" style="display: none;" username="{{ request.user.username }}" article_id="{{ article.pk }}"></div>

    {#点赞,反对#}
    <script>
        $(".action .action1").click(function () {
            if ($(".info").attr("username")) {
                {% comment %}如果当前点击的块中有...up这个类就是true{% endcomment %}
                var is_up = $(this).hasClass("glyphicon-thumbs-up");
                var article_id = "{{ article.pk }}";
                $.ajax({
                    url: "/blog/up_down/",
                    type: "get",
                    data: {
                        "is_up": is_up,
                        "article_id": article_id,
                        {#"csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val()#}
                    },
                    success: function (data) {
                        if (data.status) {
                            if (is_up) {
                                var v = $("#digg_count").text();
                                v = parseInt(v) + 1;
                                $("#digg_count").text(v);
                            }
                            else {
                                var v = $("#bury_count").text();
                                v = parseInt(v) + 1;
                                $("#bury_count").text(v);
                            }
                        }
                        else {
                            if ($(".action").click()) {
                                $("#error").html("您已经推荐过");
                                setTimeout(function () {
                                    $("#error").html("");
                                }, 1000)
                            }
                            else if ($(".action1").click()) {
                                $("#error").html("您已经反对过");
                                setTimeout(function () {
                                    $("#error").html("");
                                }, 1000)
                            }
                        }
                    }
                })
            }
            else {
                location.href = "/login/"
            }

        })
    </script>

    {# 根评论and子评论#}
    <script>
        //获取评论数据,展示评论树

        $.ajax({
            url: "blog/comment_tree/" + '{{ article.pk }}/',
            type: "get",
            success: function (data) {
                console.log(data);
                $.each(data, function (index, comment_dict) {
                    var s = '<div style="margin-left:20px" comment_id="' + comment_dict.pk + '">\n' + '<span class="content">' + comment_dict.content + '</span>\n' + '</div>'
                    if (comment_dict.parent_comment_id) {
                        //子评论
                        pid = comment_dict.parent_comment_id;
                        $("[comment_id=" + pid + "]").append(s)
                    } else {//根评论

                        $(".comment_tree").append(s)
                    }
                })
            }
        });


        //提交评论
        var pid = "";
        $("#comment_btn").click(function () {
            var article_id = $(".info").attr("article_id");
            var content = $("#comment_content").val();
            if (pid) {
                //子评论把用户名截掉
                var index = content.indexOf("\n");
                content = content.slice(index + 1);
            }

            $.ajax({
                url: "/blog/comment/",
                type: "get",
                data: {
                    article_id: article_id,
                    content: content,
                    pid: pid,
                },
                success: function (data) {
                    console.log(data);

                    var comment_li = '<li class="list-group-item"> <div> <span style="color: gray;">' + data.create_time + '</span>&nbsp;&nbsp; <span>' + data.username + '</span> <a href="" class="pull-right"><span>回复</span></a> </div> <div class="con"> <p> ' + data.content + ' </p> </div> </li>';
                    //标签
                    $(".comment_list").append(comment_li);

                    if (pid) {
                        var comment_li = '<div class="pid_info">\n' + '<p>' + data.comment_parent_username + '&nbsp;&nbsp;&nbsp;' + data.comment_parent_content + '</p>\n' + '</div>';
                        $(".comment_list").append(comment_li);
                    }
                    //清空输入框
                    $("#comment_content").val("");
                    //清空pid
                    pid = "";
                }
            })
        });
        {# 回复按钮   #}
        $(".list-group-item .reply_btn").click(function () {
            $("#comment_content").focus();
            var v = "@" + $(this).attr("username");
            $("#comment_content").val(v + ":\n");
            pid = $(this).attr("comment_pk");
        })
    </script>



{% endblock %}

后端

1.article_detail:通过文章id拿到文章对象,通过用户名拿到用户对象,通过用户对象拿到博客对象,通过文章id拿到所有的评论.
2.Comment:通过ajax传过来的父评论id,文章id和内容,保存到数据库,并且返回给前端
3.comment_tree:评论树

def article_detail(request, username, username1, pk):
    # pk是文章主键
    article_obj = models.Article.objects.filter(pk=pk).first()
    print(article_obj)
    user = models.UserInfo.objects.filter(username=username).first()
    if not user:
        return HttpResponse("404")
    blog = user.blog
    # 找到所有的评论
    comment_list = models.Comment.objects.filter(article_id=pk)
    return render(request, "article_detail.html", {"article": article_obj, "blog": blog,"comment_list":comment_list})

def comment(request):
    print(request.GET)
    pid = request.GET.get("pid")
    article_id = request.GET.get("article_id")
    content = request.GET.get("content")
    user_pk = request.user.pk
    response = {}
    if not pid:# 根评论
        comment_obj = models.Comment.objects.create(article_id=article_id,user_id=user_pk,content=content)
    else:
        comment_obj=models.Comment.objects.create(article_id=article_id,user_id=user_pk,content=content,parent_comment_id=pid)
        response["comment_parent_username"] = comment_obj.parent_comment.user.username
        response["comment_parent_content"] = comment_obj.parent_comment.content
    response["create_time"] = comment_obj.create_time
    response["content"] = comment_obj.content
    response["username"] = comment_obj.user.username

    return JsonResponse(response)

def comment_tree(request,article_id):
    print(5555)
    ret = list(models.Comment.objects.filter(article_id=article_id).values("pk","content","parent_comment_id"))
    print(ret)
    # 如果JsonResponse返回的参数不是字典,就需要加上safe参数,设置成False
    return JsonResponse(ret,safe=False)

项目地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值