Django實現文章按年月歸檔、點贊和評論、發送郵件

文章歸檔的實現

咱們在建立文章時,會在數據庫中存儲文章建立的時間這樣的字段,通常用的都是datetime類型,記錄文章建立的年月日和時分秒,因此咱們直接使用文章的建立時間分類是沒法實現文章的按年月歸檔的,由於每一篇文章的時間是不同的,因此咱們在使用ORM查詢時就沒法作到按年月分類的需求,這是就須要額外的SQL語句來實現,在SQL語句中有一個很重的時間格式化的方法:date_formatcss

  咱們可使用ORM中執行SQL語句原生用法的方法:extrahtml

from blog import models from django.db.models import Count #假設咱們獲得一個user對象 文章表中有一個create_time 字段
achive = models.Article.objects.filter(user=user).extra( select={"archive":"date_format(create_time,'%%Y-%%m')" } ).values("archive").annotate(c=Count('pk')).values("archive","c") #"pk" 在Django中代指表的主鍵

urls.py的配置python

from django.conf.urls import url from blog import views urlpatterns = [ url(r'^(\w+)/archive/(.+)/$',views.home), ]

views.pygit

                try: year, mouth = args[1].split('-') logger.debug('年:{} 月:{}'.format(year, mouth)) article_list = models.Article.objects.filter(user=user).filter(create_time__year=year, create_time__month=mouth) except Exception as e: logger.error(str(e)) return HttpResponse('404')

備註:使用Django時,默認使用的UTC時間,而中國的時區爲東八區,因此會在查詢時間時帶上一個+8的字樣,因此經過fliter查找字段時,直接等於year或者month是沒法查出須要的對象的,這是咱們須要在settings.py文件中,修改一個參數:USE_TZ = True  改成False 就能夠了。ajax

點讚的實現

點贊部分的HTML實現數據庫

    <div class="clearfix">
        <div id="div_digg">
            <div class="diggit">
                <span class="diggnum" id="digg_count">{{ article.up_count }}</span>
            </div>
            <div class="buryit">
                <span class="burynum" id="bury_count">{{ article.down_count }}</span>
            </div>
            <div class="clear"></div>
            <div class="diggword" id="digg_tips" style="color: red;"></div>
        </div>
    </div>
// 備註;若是js的實現是做爲一個靜態文件導入時,須要在HTML頁面中隱藏一個標籤,這個標籤存儲咱們在靜態文件中須要的值
<div class="info" article_id="{{ article.pk }}" username="{{ request.user.username }}" style="display: none"></div>
 

備註:在bootstarp中會自帶一個清除父標籤塌陷的樣式類方法  (class="clearfix")django

點讚的相關css樣式json

#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;
} .clear { clear: both;
}
點贊效果實現的相關css樣式

 

點贊幫點事件併發ajax請求服務器

$("#div_digg .action").click(function () { if ($(".info").attr("username")) { // 點贊或踩滅 經過判斷有無某個樣式類來區分是點贊仍是踩,以點贊中的diggit樣式類參考,若是爲點贊,則返回true,爲踩,返回false
        var is_up = $(this).hasClass("diggit"); var article_id = $(".info").attr("article_id"); $.ajax({ url: "/blog/up_down/", type: "post", data: { is_up: is_up, article_id: article_id, csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(), }, success: function (data) { // console.log(data);
                if (data.state) {// 對當前文章首次贊或者滅成功

                    if (is_up) { var val = $("#digg_count").text(); val = parseInt(val) + 1; $("#digg_count").text(val); } else { var val = $("#bury_count").text(); val = parseInt(val) + 1; $("#bury_count").text(val); } } else {    // 重複提交

                    if (data.fisrt_action) { $("#digg_tips").html("您已經推薦過"); } else { $("#digg_tips").html("您已經反對過"); } setTimeout(function () { $("#digg_tips").html("") }, 1000) } } }) } else { // 沒有登陸 就跳轉登陸
        location.href = "/login/" } });
靜態文件版

 

點贊urls.py (ajax請求相關)併發

from django.conf.urls import url from blog import views urlpatterns = [ url(r"up_down/",views.up_down), ]

 

點贊處理ajax請求的視圖函數

def up_down(request): article_id=request.POST.get('article_id') is_up=json.loads(request.POST.get('is_up')) user=request.user response={"state":True} try: models.ArticleUpDown.objects.create(user=user,article_id=article_id,is_up=is_up) models.Article.objects.filter(pk=article_id).update(up_count=F("up_count")+1) except Exception as e: response["state"]=False response["fisrt_action"]=models.ArticleUpDown.objects.filter(user=user,article_id=article_id).first().is_up return JsonResponse(response)

評論的實現

評論樹和評論樓兩種方式:

 

評論的相關路由

from django.conf.urls import url from blog import views urlpatterns = [ url(r"comment/",views.comment), url(r"comment_tree/(\d+)/",views.comment_tree), ]

 

評論的相關視圖函數

def comment(request): print(request.POST) pid=request.POST.get("pid") article_id=request.POST.get("article_id") content=request.POST.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["create_time"]=comment_obj.create_time.strftime("%Y-%m-%d") response["content"]=comment_obj.content response["username"]=comment_obj.user.username return JsonResponse(response) def comment_tree(request,article_id): ret=list(models.Comment.objects.filter(article_id=article_id).values("pk","content","parent_comment_id")) print(ret) return JsonResponse(ret,safe=False)

 

評論的HTML相關

    <p>評論樹</p>

    <div class="comment_tree"> // 評論樹內容相關 </div>
    <hr>
    
    
    <p>評論樓</p>
    <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 H:i" }}</span> &nbsp;&nbsp;
                    <a href=""><span>{{ comment.user.username }}</span></a>
                    <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 well">
                        <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> {% if request.user.username %} <div class="div_comment">
            <p>暱稱:<input type="text" id="tbCommentAuthor" class="author" disabled="disabled" size="50" value="{{ request.user.username }}"></p>
            <p>評論內容</p>
            <textarea name="" id="comment_content" cols="60" rows="10"></textarea>
            <p>
                <button id="comment_btn">提交評論</button>
            </p>

        </div> {% else %} <a href="/login/">登陸</a> {% endif %}

 

評論的js實現

<script>
        // 獲取評論數據,展現評論樹結構
 $.ajax({ url: "/blog/comment_tree/" + '{{ article.pk }}/', success: function (data) { console.log(data); $.each(data, function (index, comment_dict) { var s = '<div class="comment_item" comment_id=' + comment_dict.pk + '> <span class="content">' + comment_dict.content + '</span> </div>'
                    if (comment_dict.parent_comment_id) { // 子評論
                        var perid=comment_dict.parent_comment_id; $("[comment_id="+perid+"]").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: "post", data: { article_id: article_id, content: content, pid: pid, csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(), }, success: function (data) { console.log(data); var create_time = data.create_time; var content = data.content; var username = data.username;              if (arg.status){
         // 是根評論
var comment_li = '<li class="list-group-item"><div><span style="color: gray">' + create_time

            + '</span> &nbsp;&nbsp; <a href=""><span>' + username + '</span></a></div> <div class="con">
            <p> ' + content + ' </p> </div> </li>'; $(".comment_list").append(comment_li);
            }else{
          // 是子評論
          var parent_name = arg.parent_username;
          var par_content = arg.parent_content;
          var m = '<li class="list-group-item"><div><span>' + create_time + '&nbsp;&nbsp;</span><span>' +
        username + '&nbsp;&nbsp;</span>' + '</div><div class="well">'+parent_name+':'
              +par_content+'</div><div>' + content + '</div></li>';
        $(".list-group").append(m);
          }
            // 清空文本框 $("#comment_content").val('');
            
// 清空pid pid = ""
            }
        })
    });
// 回覆按鈕事件
$(
".list-group-item .reply_btn").click(function () {
$(
"#comment_content").focus();
var v = "@" + $(this).attr("username") + "\n"; $("#comment_content").val(v);

//pid賦值 pid = $(this).attr("comment_pk") })

</script>

 

另外Django中也提供了發送郵件的方法,不須要咱們直接使用email模塊

from django.core.mail import send_mail

 

Django實現發郵件

1 首先去本身的郵箱申請,在設置裏面找,申請開通smtp服務,我用的是163郵箱

 

2 在項目下settings.py中添加設置:

複製代碼
 1 # 配置郵箱發郵件的相關功能  2  3 #這一項是固定的  4 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'  5 # smtp服務的郵箱服務器 我用的是163  6 EMAIL_HOST = 'smtp.163.com'  7 # smtp服務固定的端口是25  8 EMAIL_PORT = 25  9 #發送郵件的郵箱 10 EMAIL_HOST_USER = 'xxxx@163.com' 11 #在郵箱中設置的客戶端受權密碼 12 EMAIL_HOST_PASSWORD = 'xxxx' 13 #收件人看到的發件人 <此處要和發送郵件的郵箱相同> 14 EMAIL_FROM = 'python<xxxx@163.com>'
複製代碼

 

3 配置好映射urls.py, 建立好視圖,.... 這些步驟省略了.....找到相應視圖後

4 在視圖中調用以下函數 便可發送郵件:

複製代碼
 1 from django.conf import settings  2 from django.core.mail import send_mail  3 from django.http import HttpResponse  4 ...  5 def send(request):  6 msg='<a href="哈哈哈" target="_blank">點擊激活</a>'  7 send_mail('標題','內容',settings.EMAIL_FROM,  8 '目標郵箱',  9 html_message=msg) 10 return HttpResponse('ok')
複製代碼

注意要 導入 settings模塊,和send_email模塊

調用send_mail() 函數即發送郵件,具體參數以下

send_mail( 標題,文字內容,發件郵箱,目的郵箱,html標籤內容 )

相關文章
相關標籤/搜索