7 功能5:文章詳情頁、評論、評論樹

一、文章詳情頁之評論如何實現?

 

 二、根評論

一、根評論樣式

 

  

 

 input.author { background-image: url('/static/img/icon_form.gif'); background-repeat: no-repeat; border: 1px solid #ccc;
 padding: 4px 4px 4px 30px; width: 230px; }

 

<div class="comments">
                    <p>發表評論</p>
                    <p>暱稱</p><input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value={{ request.user.username }}>
                    <p>評論內容</p>
                    <textarea name="" id="" cols="60" rows="10"></textarea>
                    <p>
                        <button class="btn btn-default comment_btn">提交評論</button>
                    </p>
                </div>

 

 

二、提交根評論

 

 

 

 

 

 

 三、顯示根評論

 

<p>評論列表</p>
                    <ul class="list-group comment_list"> {% for comment in comment_list %} <li class="list-group-item">
                                <div class="comment_head">
                                    <a href=""># {{ forloop.counter }}樓</a>&nbsp;&nbsp;
                                    <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span>&nbsp;&nbsp;
                                    <a href="">{{ comment.user.username }}</a>
                                    <a href="" class="pull-right">回覆</a>
                                </div>

                                <div class="comment_content">
                                    <p>{{ comment.content }}</p>
                                </div>
                            </li> {% endfor %} </ul>
評論列表

 

 四、ajax顯示評論:es6 模板字符串

  • ES6引入了模板字符串解決 字符串拼接問題+++

  深刻了解es6 模板字符串 https://www.cnblogs.com/bfc0517/p/6700849.htmlcss

def comment(request): """評論視圖""" article_id = request.POST.get("article_id") content = request.POST.get("content") parent_id = request.POST.get("parent_id") user_id = request.user.pk # 建立一條評論
    comment_obj = models.Comment.objects.create(user_id=user_id,article_id=article_id, content=content,parent_comment_id=parent_id) response = {} response["create_time"] = comment_obj.create_time.strftime("%Y-%m-%d %X") response["username"] = request.user.username response["content"] = content return JsonResponse(response)
根評論視圖

//評論請求
$('.comment_btn').click(function () { var parent_id = ""
        var content = $("#comment_content").val() $.ajax({ url: '/comment/', type: "post", data: { "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(), "article_id":{{ article_obj.pk }}, "content": content, "parent_id": parent_id }, success: function (data) { console.log(data); // dom操做 es6 標籤字符串
                var create_time = data.create_time var username = data.username var content = data.content var s = ` <li class="list-group-item">
                            <div class="comment_head">
                                <span>${create_time}</span>&nbsp;&nbsp;
                                <a href="">${username}</a>
                                <a href="" class="pull-right">回覆</a>
                            </div>

                            <div class="comment_content">
                                <p>${content}</p>
                            </div>
                        </li>`;
 $("ul").append(s) //清空評論框
                $("#comment_content").val("") } }) })
View Code

 

 

 

三、子評論

 

一、回覆按鈕

 

二、提交子評論

 

若是是子評論,就從\n開始取字符串

 

 

# indexOf()
定義和用法 indexOf() 方法可返回某個指定的字符串值在字符串中首次出現的位置。 語法 stringObject.indexOf(searchvalue,fromindex) # slice()
定義和用法 slice() 方法可從已有的數組中返回選定的元素。 語法 arrayObject.slice(start,end)

 

 

三、render顯示子評論

 

 

 四、ajax顯示子評論

if 父評論html

  顯示s  前端

若是子評論jquery

  顯示 新的樣式git

 

四、評論樹

一、評論樹簡介

  一、方式1:遞歸完成
     二、方式2:評論樹展現數據

 

二、評論樹的請求數據

# 評論
    re_path('^comment/$', views.comment, name='comment'), # 評論樹
    re_path('^get_comment_tree/$', views.get_comment_tree, name='get_comment_tree'),

 

def get_comment_tree(request): """評論樹""" article_id = request.GET.get("article_id") ret = list(models.Comment.objects.filter(article_id=article_id).values("pk", "content","parent_comment_id")) return JsonResponse(ret,safe=False)

     

 

 三、展開評論樹1:根評論

 

 

 

 四、展開評論樹2:子評論

 

 

 

 五、評論樹思考

 

//評論樹 $(".tree_btn").click(function () { $.ajax({ url: "/get_comment_tree/", type: "get", data: { article_id:{{ article_obj.pk }} }, success: function (comment_list) { console.log(comment_list) $.each(comment_list, function (index, comment_object) { var pk = comment_object.pk var content = comment_object.content var parent_comment_id = comment_object.parent_comment_id var s = '<div class="comment_item" comment_id=' + pk + '><span>' + content + '</span>' + '</div>'

                    if (!parent_comment_id) { //根評論展現 $(".comment_tree").append(s) } else { //子評論展現 $("[comment_id="+parent_comment_id+ "]").append(s) } }) } }) })

 

 

 五、評論之事務操做

  事務同步:同進同退es6

 

 

六、郵件發送評論

 

django中配置郵件 ajax

https://blog.csdn.net/xinxinnogiveup/article/details/78900811django

https://code.ziqiangxuetang.com/django/django-send-email.htmljson

 

 

一、settings配置

# 發送郵件
EMAIL_USE_SSL = True # EMIAL_HOST = 'smtp.exmail.qq.com' # 若是是163 改爲smtp.163.com
EMAIL_HOST = 'smtp.qq.com'  # 若是是 163 改爲 smtp.163.com
EMAIL_PORT = 465 EMAIL_HOST_USER = '7xxxxxxxx@qq.com'        # 帳號
EMAIL_HOST_PASSWORD = 'oXXXXXxxxxx'    # qq郵箱的受權碼而不是密碼
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER 

qq郵箱受權碼如何開啓?bootstrap

 http://service.mail.qq.com/cgi-bin/help?id=28&no=1001256&subtype=1

 

 

二、from django.core.mail import send_mail

 

 

 

三、多進程實現

 

 

 

 六、評論的完整代碼

url

# 我的站點頁面設計
    re_path(r'^(?P<username>\w+)$', views.home_site, name='home_site'), # 我的站點的跳轉
    re_path(r'^(?P<username>\w+)/(?P<condition>tag|category|archive)/(?P<param>.*)/$', views.home_site, name='home_site'), # 文章詳情頁
    re_path(r'^(?P<username>\w+)/articles/(?P<article_id>\d+)$', views.article_detail, name='article_detail'), # 點贊
    re_path('^digg/$', views.digg, name='digg'), # 評論
    re_path('^comment/$', views.comment, name='comment'), # 評論樹
    re_path('^get_comment_tree/$', views.get_comment_tree, name='get_comment_tree'),
View Code

 

settings

LANGUAGE_CODE = 'en-us'


# 時區選擇 # TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True # 轉換時區 # USE_TZ = True
USE_TZ = False # 發送郵件
EMAIL_USE_SSL = True # EMIAL_HOST = 'smtp.exmail.qq.com' # 若是是163 改爲smtp.163.com
EMAIL_HOST = 'smtp.qq.com'  # 若是是 163 改爲 smtp.163.com
EMAIL_PORT = 465 EMAIL_HOST_USER = '7fadfasas0@qq.com'        # 帳號
EMAIL_HOST_PASSWORD = 'ord大師傅bdie'    # qq郵箱的受權碼而不是密碼
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
View Code

 

view視圖

from django.shortcuts import render, HttpResponse, redirect from blog.utils.validCode import get_validCode_img  # 導入驗證碼函數
from django.http import JsonResponse  # Json數據返回到前端
from django.contrib import auth  # 用戶認證組件
from blog.models import UserInfo from blog.myForms import UserForm  # froms組件
from blog import models from django.db.models import Avg, Max, Min, Count, F, Q from django.db import transaction  # 事務操做



def article_detail(request, username, article_id): """文章詳情頁""" user_obj = models.UserInfo.objects.filter(username=username).first() blog = user_obj.blog # article_id對應的文章
    article_obj = models.Article.objects.filter(pk=article_id).first() # 評論顯示
    comment_list = models.Comment.objects.filter(article_id=article_id) return render(request, 'blog/article_detail.html', locals()) import json def digg(request): """點贊視圖"""
    # print(request.POST)
    article_id = request.POST.get("article_id") # article_id = request.POST.get("is_up") # true
    is_up = json.loads(request.POST.get("is_up"))  # True
    user_id = request.user.pk  # 點贊人即爲登陸人

    # 點贊記錄以及存在
    from django.http import JsonResponse  # Json數據返回到前端
    response = {"state": True, "msg": None, "handled": None} obj = models.ArticleUpDown.objects.filter(user_id=user_id, article_id=article_id).first() if not obj: # 建立一條點贊記錄
        ard = models.ArticleUpDown.objects.create(user_id=user_id, is_up=is_up, article_id=article_id) from django.db.models import F # 點贊數的保存
        queryset = models.Article.objects.filter(pk=article_id) if is_up: queryset.update(up_count=F("up_count") + 1) else: queryset.update(down_count=F("down_count") - 1) else: response['state'] = False response['handled'] = obj.is_up return JsonResponse(response) def comment(request): """評論視圖""" article_id = request.POST.get("article_id") content = request.POST.get("content") parent_id = request.POST.get("parent_id") user_id = request.user.pk article_obj = models.Article.objects.filter(pk=article_id).first() with transaction.atomic(): # 事務操做
        # 建立一條評論
        comment_obj = models.Comment.objects.create(user_id=user_id, article_id=article_id, content=content, parent_comment_id=parent_id) # yun # 事務中斷
        # 評論 comment_count +1
        models.Article.objects.filter(pk=article_id).update(comment_count=F("comment_count") + 1) # 發送郵件
    from django.core.mail import send_mail from cnblog import settings """ send_mail( "你的文章【%s】新增了一條評論內容" % article_obj.title, content, settings.EMAIL_HOST_USER, ['849923747@qq.com'] ) """

    import threading  # 多進程發送郵件
    t = threading.Thread(target=send_mail, args=("你的文章【%s】新增了一條評論內容" % article_obj.title, content, settings.EMAIL_HOST_USER, ["849923747@qq.com"] )) t.start() response = {} response["create_time"] = comment_obj.create_time.strftime("%Y-%m-%d %X") response["username"] = request.user.username response["content"] = content return JsonResponse(response) def get_comment_tree(request): """評論樹""" article_id = request.GET.get("article_id") ret = list(models.Comment.objects.filter(article_id=article_id).order_by("pk").values("pk", "content", "parent_comment_id")) return JsonResponse(ret, safe=False)
View Code

 

templatetags/my_tags

# -*- coding: utf-8 -*- # @Time : 2018/08/04 0004 22:03 # @Author : Venicid

from django import template from django.db.models import Count from blog import models register = template.Library() @register.inclusion_tag("blog/classification.html") def get_classification_style(username): user_obj = models.UserInfo.objects.filter(username=username).first() blog = user_obj.blog cate_list = models.Category.objects.filter(blog=blog).values('pk').annotate(c=Count("article__title")).values_list("title", 'c') tag_list = models.Tag.objects.filter(blog=blog).values('pk').annotate(c=Count('article')).values_list('title','c') date_list = models.Article.objects.filter(user=user_obj).extra(select={'y_m_date':"date_format(create_time,'%%Y-%%m')"}).values('y_m_date').annotate(c=Count('nid')).values_list('y_m_date', 'c') return {'blog':blog,"tag_list":tag_list,"date_list":date_list, "cate_list":cate_list} @register.simple_tag def multi_tag(x,y): return x*y
View Code

 

.模板層

article_detail.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap3/css/bootstrap.css">
    <script src="/static/js/jquery-3.2.1.min.js"></script>
    <style type="text/css"> .glyphicon-comment { vertical-align: -1px;
        } #div_digg { float: right; margin-bottom: 10px; margin-right: 30px; font-size: 12px; width: 125px; text-align: center; margin-top: 10px;
        } .diggit { float: left; width: 46px; height: 52px; background: url('/static/img/upup.gif') no-repeat; text-align: center; cursor: pointer; margin-top: 2px; padding-top: 5px;
        } .buryit { float: right; margin-left: 20px; width: 46px; height: 52px; background: url('/static/img/downdown.gif') no-repeat; text-align: center; cursor: pointer; margin-top: 2px; padding-top: 5px;
        } #digg_tips { color: red; clear: both;
        } input.author { background-image: url('/static/img/icon_form.gif'); background-repeat: no-repeat; border: 1px solid #ccc; padding: 4px 4px 4px 30px; width: 230px;
        } .comment_content { margin-top: 5px;
        } .reply_btn { color: #369; cursor: pointer;

        } .comment_item{ margin-left: 20px;
        }
    </style>
</head>
<body>


<div class="site-header">
    <nav class="navbar navbar-inverse">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" href="#"> {{ blog.title }} </a>
            </div>
            <div class="navbar-header pull-right">
                <a class="navbar-brand" href="#"> 管理 </a>
            </div>
        </div>
    </nav>

</div>

<div class="container-fluid">
    <div class="row">
        <div class="col-md-3"> {% load my_tags %} {% get_classification_style username %} </div>


        <div class="col-md-8"> {% csrf_token %} <div class="article_info ">
                <h3 class="text-center">{{ article_obj.title }}</h3>
                <div> {{ article_obj.content|safe }}</div>

                <div class="clearfix">
                    <div id="div_digg">
                        <div class="diggit action">
                            <span class="diggnum" id="digg_count">{{ article_obj.up_count }}</span>
                        </div>
                        <div class="buryit action">
                            <span class="burynum" id="bury_count">0</span>
                        </div>
                        <div class="clear"></div>
                        <div class="diggword" id="digg_tips"></div>
                    </div>
                </div>

                <div class="comments list-group">
                    <p class="tree_btn">評論樹</p>
                    <div class="comment_tree">

                        <div class="comment_tree">

                        </div>
                    </div>


                    <p>評論列表</p>
                    <ul class="list-group comment_list"> {% for comment in comment_list %} <li class="list-group-item">
                                <div class="comment_head">
                                    <a href=""># {{ forloop.counter }}樓</a>&nbsp;&nbsp;
                                    <span>{{ comment.create_time|date:"Y-m-d H:i" }}</span>&nbsp;&nbsp;
                                    <a href="">{{ comment.user.username }}</a>
                                    <span class="pull-right reply_btn" username="{{ comment.user.username }}" parent_comment_pk="{{ comment.pk }}">回覆</span>
                                </div> {% if comment.parent_comment_id %} <div class="parent_info well">
                                        <p>{{ comment.parent_comment.user.username }}:{{ comment.parent_comment.content }}</p>
                                    </div> {% endif %} <div class="comment_content">
                                    <p>{{ comment.content }}</p>
                                </div>

                            </li> {% endfor %} </ul>

                    <p>發表評論</p>
                    <p>暱稱</p><input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}">
                    <p>評論內容</p>
                    <textarea name="" id="comment_content" cols="60" rows="10"></textarea>
                    <p>
                        <button class="btn btn-default comment_btn">提交評論</button>
                    </p>
                </div>

            </div>
        </div>
    </div>
</div>

<script>
    //點贊請求
 $("#div_digg .action").click(function () { var is_up = $(this).hasClass("diggit"); $obj = $(this).children("span"); // 獲取點贊數
 $.ajax({ url: "/digg/", type: "post", data: { "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(), "is_up": is_up, "article_id":{{ article_obj.pk }} }, success: function (data) { // 點贊 +1
                if (data.state) { var val = parseInt($obj.text()); $obj.text(val + 1) } else { //點贊過了
                    var val = data.handled ? "您已經推薦過了" : "您已經反對過了" $('#digg_tips').html(val) setTimeout(function () { $("#digg_tips").html("") }, 2000) } } }) }) //評論請求
    var parent_id = ""; $('.comment_btn').click(function () { var content = $("#comment_content").val() if (parent_id) { var index = content.indexOf("\n") content = content.slice(index + 1) } $.ajax({ url: '/comment/', type: "post", data: { "csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val(), "article_id":{{ article_obj.pk }}, "content": content, "parent_id": parent_id }, success: function (data) { console.log(data); // dom操做 es6 標籤字符串
                var create_time = data.create_time var username = data.username var content = data.content var s = ` <li class="list-group-item">
                            <div class="comment_head">
                                <span>${create_time}</span>&nbsp;&nbsp;
                                <a href="">${username}</a>
                                <a class="pull-right">回覆</a>
                            </div>

                            <div class="comment_content">
                                <p>${content}</p>
                            </div>
                        </li>`;
 $("ul.comment_list").append(s) //清空評論框
 parent_id = "" $("#comment_content").val("") } }) }) //回覆按鈕事件
 $(".reply_btn").click(function () { $("#comment_content").focus() var val = "@" + $(this).attr("username") + "\n"; $("#comment_content").val(val) parent_id = $(this).attr("parent_comment_pk") }) //評論樹
 $(".tree_btn").click(function () { $.ajax({ url: "/get_comment_tree/", type: "get", data: { article_id:{{ article_obj.pk }} }, success: function (comment_list) { console.log(comment_list) $.each(comment_list, function (index, comment_object) { var pk = comment_object.pk var content = comment_object.content var parent_comment_id = comment_object.parent_comment_id var s = '<div class="comment_item" comment_id=' + pk + '><span>' + content + '</span>' + '</div>'

                    if (!parent_comment_id) { //根評論展現
 $(".comment_tree").append(s) } else { //子評論展現
 $("[comment_id="+parent_comment_id+ "]").append(s) } }) } }) }) </script>
</body>
</html>
View Code

 

 

classifications.html

<div>
            <div class="panel panel-warning">
                <div class="panel-heading">個人標籤</div>
                <div class="panel-body"> {% for tag in tag_list %} <p><a href="/{{ username }}/tag/{{ tag.0 }}">{{ tag.0 }}({{ tag.1 }})</a></p> {% endfor %} </div>
            </div>
            <div class="panel panel-warning">
                <div class="panel-heading">隨筆分類</div>
                <div class="panel-body"> {% for cate in cate_list %} <p><a href="/{{ username }}/category/{{ cate.0 }}">{{ cate.0 }}({{ cate.1 }})</a></p> {% endfor %} </div>
            </div>
            <div class="panel panel-warning">
                <div class="panel-heading">隨筆歸檔</div>
                <div class="panel-body"> {% for date in date_list %} <p><a href="/{{ username }}/archive/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p> {% endfor %} </div>
            </div>
        </div>
View Code

 

 

home_site.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap3/css/bootstrap.css">
    <style type="text/css"> .glyphicon-comment { vertical-align: -1px;
        }
    </style>
</head>
<body>
<div class="site-header">
    <nav class="navbar navbar-inverse">
        <div class="container-fluid">
            <div class="navbar-header">
                <a class="navbar-brand" href="#"> {{ blog.title }} </a>
            </div>
            <div class="navbar-header pull-right">
                <a class="navbar-brand" href="#"> 管理 </a>
            </div>
        </div>
    </nav>

</div>

<div class="container-fluid">
    <div class="row">
        <div class="col-md-3">
            <div class="panel panel-warning">
                <div class="panel-heading">個人標籤</div>
                <div class="panel-body"> {% for tag in tag_list %} <p><a href="/{{ username }}/tag/{{ tag.0 }}">{{ tag.0 }}({{ tag.1 }})</a></p> {% endfor %} </div>
            </div>

            <div class="panel panel-warning">
                <div class="panel-heading">隨筆分類</div>
                <div class="panel-body"> {% for cate in cate_list %} <p><a href="/{{ username }}/category/{{ cate.0 }}">{{ cate.0 }}({{ cate.1 }})</a></p> {% endfor %} </div>
            </div>
            <div class="panel panel-warning">
                <div class="panel-heading">隨筆歸檔</div>
                <div class="panel-body"> {% for date in date_list %} <p><a href="/{{ username }}/archive/{{ date.0 }}">{{ date.0 }}({{ date.1 }})</a></p> {% endfor %} </div>
            </div>
        </div>
        <div class="col-md-8"> {% for article in article_list %} <div class="article-item clearfix">
                    <h5><a href="">{{ article.title }}</a></h5>
                    <div class="article-desc">
                        <span>{{ article.desc }}</span>
                    </div>
                    <div class="small pub_info pull-right ">
                        <span>發佈於&nbsp;&nbsp;{{ article.create_time|date:"Y-m-d H:m:s" }}</span>&nbsp;&nbsp;&nbsp;
                        <span class="glyphicon glyphicon-comment">評論({{ article.comment_count }})</span>&nbsp;&nbsp;&nbsp;
                        <span class="glyphicon glyphicon-thumbs-up">點贊({{ article.up_count }})</span>
                    </div>
                </div>
                <hr> {% endfor %} </div>
    </div>
</div>

</body>
</html>
View Code
相關文章
相關標籤/搜索