1. 程式人生 > 其它 >BBS專案分佈搭建五(評論相關功能實現)

BBS專案分佈搭建五(評論相關功能實現)

BBS專案分佈搭建五(評論相關)

1. 根評論邏輯實現

# 在models.py檔案中 修改:
# 7. 評論表
    parent = models.ForeignKey(to='self', null=True)
    
    
# 新增路由(最好放在文章詳情之上):
    # 評論功能
    url(r'^comment/', views.comment),
    
    
# 在views.py中 新增功能:
# 10. 評論功能
def comment(request):
    if request.is_ajax() and request.method == 'POST':
        back_dic = {'status': 200, 'msg': '評論成功'}


        # 1. 接收引數
        content = request.POST.get('content')
        article_id = request.POST.get('article_id')


        # 2. 驗證引數
        if not content:
            back_dic['status'] = 1013
            back_dic['msg'] = '評論內容不能為空哦~'
            return JsonResponse(back_dic)

        if not article_id:
            back_dic['status'] = 1014
            back_dic['msg'] = '評論的文章不存在'
            return JsonResponse(back_dic)


        # 3. 驗證是否登入,驗證儘量的完善
        if not request.session.get('username'):
            back_dic['status'] = 1015
            back_dic['msg'] = '請先登入在評論'
            return JsonResponse(back_dic)


        # 4. 處理評論邏輯
        # 4.1 操作評論表,文章表(評論數)
        # 3.2 事務:保證資料安全,ACID四大特性,原子性,保證的是同一個事務中的SQL必須同時成功,同時失敗
        # 3.3 在企業中,遇到跟財務相關的需求,儘量都要使用事務
        from django.db import transaction

        with transaction.atomic():
            models.Article.objects.filter(pk=article_id).update(comment_num=F('comment_num') + 1)
            models.Comment.objects.create(
                content=content,
                article_id=article_id,
                user_id=request.session.get('id'),
            )
        return JsonResponse(back_dic)

    return HttpResponse('ok')



# 修改article_detail.html檔案
# 在 {% block content %} 標籤中新增以下內容:
    {#    評論樣式開始#}
    {% if request.session.username %}
    <div >
        <p>
            <span class="glyphicon glyphicon-comment"></span>發表評論
        </p>
        <p>
            <textarea name="" id="content" cols="30" rows="10"></textarea>
        </p>
        <p>
            <input type="button" class="btn btn-success commit" value="提交">
        </p>
    </div>
    {% endif %}
    {#    評論樣式結束#}
        

# 在 {% block js %} </script> 標籤中新增以下內容:
        // 提交評論
        $(".commit").click(function () {
            // 先獲取評論內容
            var content = $('#content').val();
            var article_id = '{{ article_id }}';  // 拿到文章id比對

            // 提交ajax
            $.ajax({
                url: '/comment/',
                type: 'post',
                data: {'content': content, article_id: article_id, },
                success: function (res) {
                    console.log(res);
                }
             })
        })
    </script>


2. 評論內容前端列表樣式準備

# 修改article_detail.html檔案
# 在 {% block content %}標籤中新增:
    
    {#    評論列表開始#}
    <div class="comment">
        <h1>評論列表</h1>
        <ul class="list-group">
                <li class="list-group-item">
                    <span style="margin-right: 10px;color: #399ab2"># 1樓</span> <span style="margin-right: 10px">2022-03-08</span> <span style="color: #399ab2">吾 荒天帝</span>
                    <span style="margin-right: 10px">{{ comment.create_time|date:'Y-m-d H:i' }}</span>
                    <span style="color: #399ab2">{{ comment.user.username }}</span>
                    <span><a href="" class="pull-right reply" style="text-decoration: none;">回覆</a></span>
                    <p style="margin-top: 10px;margin-left: 15px;">
                        一劍斷萬古! 他化自在,他化萬古!
                    </p>
                </li>
        
                <li class="list-group-item">
                    <span style="margin-right: 10px;color: #399ab2"># 1樓</span> <span style="margin-right: 10px">2022-03-08</span> <span style="color: #399ab2">吾 荒天帝</span>
                    <span style="margin-right: 10px">{{ comment.create_time|date:'Y-m-d H:i' }}</span>
                    <span style="color: #399ab2">{{ comment.user.username }}</span>
                    <span><a href="" class="pull-right reply" style="text-decoration: none;">回覆</a></span>
                    <p style="margin-top: 10px;margin-left: 15px;">
                        一劍斷萬古! 他化自在,他化萬古!
                    </p>
                </li>    
        
                <li class="list-group-item">
                    <span style="margin-right: 10px;color: #399ab2"># 1樓</span> <span style="margin-right: 10px">2022-03-08</span> <span style="color: #399ab2">吾 荒天帝</span>
                    <span style="margin-right: 10px">{{ comment.create_time|date:'Y-m-d H:i' }}</span>
                    <span style="color: #399ab2">{{ comment.user.username }}</span>
                    <span><a href="" class="pull-right reply" style="text-decoration: none;">回覆</a></span>
                    <p style="margin-top: 10px;margin-left: 15px;">
                        一劍斷萬古! 他化自在,他化萬古!
                    </p>
                </li>
        
                <li class="list-group-item">
                    <span style="margin-right: 10px;color: #399ab2"># 1樓</span> <span style="margin-right: 10px">2022-03-08</span> <span style="color: #399ab2">吾 荒天帝</span>
                    <span style="margin-right: 10px">{{ comment.create_time|date:'Y-m-d H:i' }}</span>
                    <span style="color: #399ab2">{{ comment.user.username }}</span>
                    <span><a href="" class="pull-right reply" style="text-decoration: none;">回覆</a></span>
                    <p style="margin-top: 10px;margin-left: 15px;">
                        一劍斷萬古! 他化自在,他化萬古!
                    </p>
                </li>
        
                <li class="list-group-item">
                    <span style="margin-right: 10px;color: #399ab2"># 1樓</span> <span style="margin-right: 10px">2022-03-08</span> <span style="color: #399ab2">吾 荒天帝</span>
                    <span style="margin-right: 10px">{{ comment.create_time|date:'Y-m-d H:i' }}</span>
                    <span style="color: #399ab2">{{ comment.user.username }}</span>
                    <span><a href="" class="pull-right reply" style="text-decoration: none;">回覆</a></span>
                    <p style="margin-top: 10px;margin-left: 15px;">
                        一劍斷萬古! 他化自在,他化萬古!
                    </p>
                </li>
        </ul>
    </div>
    {#    評論列表結束#}
        
        

# 在 {% block css %} <style> 標籤中新增:
        .reply:hover {
            color: #9cba39;
        }
    

3. 評論後端邏輯實現

# 在views.py中 文章詳情頁功能中新增查詢評論內容:
# 8. 文章詳情頁
    # 查詢當前文章的所有評論
    comment_list = models.Comment.objects.filter(article_id=article_id).all()

    return render(request, 'article_detail.html', locals())



# 修改article_detail.html檔案
# 修改 {% block js %} </script> 標籤內的 // 提交ajax:
            // 提交ajax
            $.ajax({
                url: '/comment/',
                type: 'post',
                data: {'content': content, article_id: article_id, },
                success: function (res) {
                    console.log(res);
                    var userName = '{{ request.session.username }}'

                    if (res.status == 200) {
                        // 1. 清空評論框
                        $("#content").val('');

                        // 2. 把評論成功的資訊放到頁面上
                        $("#error_msg").text(res.msg);

                        // 3. 評論之後,渲染臨時評論  // ``反引號 引用模板語法
                        var html = `
                            <li class="list-group-item">
                                <span class="glyphicon glyphicon-comment"></span>
                                <span style="color: #399ab2">${userName}</span>
                                <p style="    margin-top: 10px;margin-left: 15px;">
                                    ${content}
                                </p>
                            </li>
                        `;

                        {#// 使用字串引號也可以達到同樣效果#}
                        {#var html = ""#}
                        {#html += '<li class="list-group-item">' +#}
                        {#    '<span class="glyphicon glyphicon-comment"></span>'#}
                        {#    + '<span style="color: #399ab2">' + userName + '</span>' +#}
                        {#    '<p style="    margin-top: 10px;margin-left: 15px;">' + content + '</p>' +#}
                        {#    '</li>';#}

                        $('.list-group').append(html);
                    }
                }
             })
        })
    </script>

4. 子評論功能實現

# 在views.py中修改 評論功能 兩處:
# 10. 評論功能
        # 1. 接收引數
        content = request.POST.get('content')
        article_id = request.POST.get('article_id')
        parent_id = 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(
                content=content,
                article_id=article_id,
                user_id=request.session.get('id'),
                parent_id=parent_id  # 二處
            )
        return JsonResponse(back_dic)

    

# 將 {#    評論列表開始#} 下面的 <span><a標籤的 href="" 刪除 達到阻止a標籤預設提交問題
	此外 也可以在 // 子評論 下資料提交中進行阻止
    
# 修改 article_detail.html檔案:
# 修改 評論列表 內容:
    {#    評論列表開始#}
    <div class="comment">
        <h1>評論列表</h1>
        <ul class="list-group">
            {% for comment in comment_list %}
                <li class="list-group-item">
                    <span style="margin-right: 10px;color: #399ab2"># {{ forloop.counter }}樓</span>
                    <span style="margin-right: 10px">{{ comment.create_time|date:'Y-m-d H:i' }}</span>
                    <span style="color: #399ab2">{{ comment.user.username }}</span>
                    <span><a class="pull-right reply" style="text-decoration: none;" username="{{ comment.user.username }}" comment_id="{{ comment.pk }}">回覆</a></span>

                    <p style="margin-top: 10px;margin-left: 15px;">
                        {% if comment.parent_id %}
                            <span>@ {{ comment.parent.user.username }}</span>
                            <p>
                                {{ comment.content }}
                            </p>
                        {% else %}
                            {{ comment.content }}
                        {% endif %}
                    </p>
                </li>

            {% endfor %}
        </ul>
    </div>
    {#    評論列表結束#}
    
        
        
# 修改 {% block js %} </script> 標籤內容:
{% block js %}
    <script>
        var parent_id = null;  // 定義全域性變數,目的是,在提交評論的事件裡使用子評論事件裡的根評論id
        $('.active').click(function () {
            var is_up = $(this).hasClass('diggit');  // true false
            var article_id = '{{ article_id }}';
            var _this = $(this)

            // 傳送ajax請求
             $.ajax({
                url: '/up_or_down/',
                type: 'post',
                data: {'is_up': is_up, article_id: article_id},
                success: function (res) {
                    console.log(res);

                    if (res.status == 200) {
                        $('.error_msg').text(res.msg);
                        var old_num = Number(_this.children().text());
                        _this.children().text(old_num + 1)
                    } else if (res.status == 1010) {
                        $('.error_msg').append(res.msg)
                    } else {
                        layer.msg(res.msg)
                    }
                }
            })
        })

        // 提交評論
        $(".commit").click(function () {
            // 先獲取評論內容
            var content = $('#content').val();
            var article_id = '{{ article_id }}';  // 拿到文章id比對

            // 重點:如何區分是根評論還是子評論
            if (parent_id) {
                // 子評論
                var num = content.indexOf('\n') + 1;
                content = content.slice(num)  // 把換行符之前的內容全部切掉
            }

            // 提交ajax
            $.ajax({
                url: '/comment/',
                type: 'post',
                data: {'content': content, article_id: article_id, parent_id: parent_id},
                success: function (res) {
                    console.log(res);
                    var userName = '{{ request.session.username }}'

                    if (res.status == 200) {
                        // 1. 清空評論框
                        $("#content").val('');

                        // 2. 把評論成功的資訊放到頁面上
                        $("#error_msg").text(res.msg);

                        // 3. 評論之後,渲染臨時評論  // ``反引號 引用模板語法
                        var html = `
                            <li class="list-group-item">
                                <span class="glyphicon glyphicon-comment"></span>
                                <span style="color: #399ab2">${userName}</span>
                                <p style="    margin-top: 10px;margin-left: 15px;">
                                    ${content}
                                </p>
                            </li>
                        `;

                        {#// 使用字串引號也可以達到同樣效果#}
                        {#var html = ""#}
                        {#html += '<li class="list-group-item">' +#}
                        {#    '<span class="glyphicon glyphicon-comment"></span>'#}
                        {#    + '<span style="color: #399ab2">' + userName + '</span>' +#}
                        {#    '<p style="    margin-top: 10px;margin-left: 15px;">' + content + '</p>' +#}
                        {#    '</li>';#}

                        $('.list-group').append(html);

                        // 根評論的id要清空
                        parent_id = null;
                    }
                }
             })
        })

        // 子評論
        $('.reply').click(function (event) {
            {#alert(123)#}

            {#阻止a標籤預設提交問題其他方法#}
            {#return false;  // 阻止預設提交, 不僅適用於a標籤,還適用於form表單#}
            {#event.preventDefault() // 阻止預設提交#}

            // 子評論邏輯
            var userName = $(this).attr('username');

            // 獲取根評論的id
            parent_id = $(this).attr('comment_id');
            var s = '@' + userName + '\n'
            $('#content').val(s).focus();
        })
    </script>
{% endblock %}