Django+Nginx+uwsgi搭建本身的博客(七)

上一篇博客中介紹了Blogs App的部分後端功能的實現,在這篇博客中,將繼續爲你們介紹Blogs App中前端功能的實現。javascript

首先來看發佈博客功能的前端頁面。在blogs/templates/blogs目錄下創建名爲addBlog.html的文件,做爲咱們的發佈博客頁面。addBlog.html內容以下:html

 

  1. <!-- addBlog.html -->  
  2. {% extends "blogTemplate.html" %}  
  3. {% block content %}  
  4. <div class="content">  
  5. <form action="{% url 'blogs:addblog' %}" method="post">  
  6. {% csrf_token %}  
  7. {{ form.as_p }}  
  8. <input type="submit" value="保存並提交">  
  9. <input type="button" id="saveDraft" value="保存到草稿">  
  10. <div id="tip" >  
  11. </div>  
  12. </form>  
  13. </div>  
  14. <script>  
  15.     CKEDITOR.replace('blogcontent',{uiColor:'#9AB8F3'});  
  16. </script>  
  17. <script>  
  18. $("#saveDraft").click(function(){  
  19.     var blogContent = "";  
  20.     try  
  21.     {  
  22.         blogContent = CKEDITOR.instances.id_content.getData();  
  23.     }  
  24.     catch(ex){}  
  25.     $.post("{% url 'blogs:saveDraft' %}",  
  26.     {  
  27.         title:$("#id_title").val(),  
  28.         category:$("#id_category").val(),  
  29.         content:blogContent,  
  30.         csrfmiddlewaretoken:'{{ csrf_token }}'  
  31.     },  
  32.     function(data,status)  
  33.     {  
  34.         var mydate = new Date();  
  35.           
  36.         $("#tip").html("<p>文章已存爲草稿於"+mydate.toLocaleString()+"</p>");  
  37.         $("#tip").show();  
  38.         $("#tip").delay(5000).hide(0);  
  39.     });  
  40. });  
  41. </script>  
  42. <script>  
  43. function saveDraft(){  
  44.     var blogContent = "";  
  45.     try  
  46.     {  
  47.         blogContent = CKEDITOR.instances.id_content.getData();  
  48.     }  
  49.     catch(ex){}  
  50.     $.post("{% url 'blogs:saveDraft' %}",  
  51.     {  
  52.         title:$("#id_title").val(),  
  53.         category:$("#id_category").val(),  
  54.         content:blogContent,  
  55.         csrfmiddlewaretoken:'{{ csrf_token }}'  
  56.     },  
  57.     function(data,status)  
  58.     {  
  59.         var mydate = new Date();  
  60.         $("#tip").html("<p>文章已存爲草稿於"+mydate.toLocaleString()+"</p>");  
  61.     });  
  62. }  
  63. setInterval(saveDraft,60000);  
  64. </script>  
  65. </div>  
  66. {% endblock %}  
<!-- addBlog.html -->
{% extends "blogTemplate.html" %}
{% block content %}
<div class="content">
<form action="{% url 'blogs:addblog' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="保存並提交">
<input type="button" id="saveDraft" value="保存到草稿">
<div id="tip" >
</div>
</form>
</div>
<script>
    CKEDITOR.replace('blogcontent',{uiColor:'#9AB8F3'});
</script>
<script>
$("#saveDraft").click(function(){
    var blogContent = "";
    try
    {
        blogContent = CKEDITOR.instances.id_content.getData();
    }
    catch(ex){}
    $.post("{% url 'blogs:saveDraft' %}",
    {
        title:$("#id_title").val(),
        category:$("#id_category").val(),
        content:blogContent,
        csrfmiddlewaretoken:'{{ csrf_token }}'
    },
    function(data,status)
    {
        var mydate = new Date();
        
        $("#tip").html("<p>文章已存爲草稿於"+mydate.toLocaleString()+"</p>");
        $("#tip").show();
        $("#tip").delay(5000).hide(0);
    });
});
</script>
<script>
function saveDraft(){
    var blogContent = "";
    try
    {
        blogContent = CKEDITOR.instances.id_content.getData();
    }
    catch(ex){}
    $.post("{% url 'blogs:saveDraft' %}",
    {
        title:$("#id_title").val(),
        category:$("#id_category").val(),
        content:blogContent,
        csrfmiddlewaretoken:'{{ csrf_token }}'
    },
    function(data,status)
    {
        var mydate = new Date();
        $("#tip").html("<p>文章已存爲草稿於"+mydate.toLocaleString()+"</p>");
    });
}
setInterval(saveDraft,60000);
</script>
</div>
{% endblock %}
這個頁面在顯示的方面比較簡單,就是將咱們在上一篇博客中創建好的BlogForm表單顯示在頁面上。注意,爲了使用CKeditor,咱們須要使用如下的javascript語句對咱們的文本域進行替換:

 

[javascript] view plain copy
print ?
  1. <script>  
  2.     CKEDITOR.replace('blogcontent',{uiColor:'#9AB8F3'});  
  3. </script>  
<script>
    CKEDITOR.replace('blogcontent',{uiColor:'#9AB8F3'});
</script>
其中,blogcontent是咱們文本域的id,而uiColor意味着咱們能夠爲這個文本框指定顏色。

在該頁面中,另一個功能是將正在編輯的文章存儲爲草稿。因爲保存草稿的操做不容許提交表單後跳轉頁面,所以咱們須要使用jquery ajax的方式提交表單。在這裏,咱們提供了兩種方式將文章保存草稿:一、經過用戶手動點擊保存按鈕來存爲草稿;二、每隔1分鐘自動保存草稿。首先來看經過按鈕來保存的javascript代碼:前端

 

[javascript] view plain copy
print ?
  1. <script>  
  2. $("#saveDraft").click(function(){  
  3.     var blogContent = "";  
  4.     try  
  5.     {  
  6.         blogContent = CKEDITOR.instances.id_content.getData();  
  7.     }  
  8.     catch(ex){}  
  9.     $.post("{% url 'blogs:saveDraft' %}",  
  10.     {  
  11.         title:$("#id_title").val(),  
  12.         category:$("#id_category").val(),  
  13.         content:blogContent,  
  14.         csrfmiddlewaretoken:'{{ csrf_token }}'  
  15.     },  
  16.     function(data,status)  
  17.     {  
  18.         var mydate = new Date();  
  19.           
  20.         $("#tip").html("<p>文章已存爲草稿於"+mydate.toLocaleString()+"</p>");  
  21.         $("#tip").show();  
  22.         $("#tip").delay(5000).hide(0);  
  23.     });  
  24. });  
  25. </script>  
<script>
$("#saveDraft").click(function(){
    var blogContent = "";
    try
    {
        blogContent = CKEDITOR.instances.id_content.getData();
    }
    catch(ex){}
    $.post("{% url 'blogs:saveDraft' %}",
    {
        title:$("#id_title").val(),
        category:$("#id_category").val(),
        content:blogContent,
        csrfmiddlewaretoken:'{{ csrf_token }}'
    },
    function(data,status)
    {
        var mydate = new Date();
        
        $("#tip").html("<p>文章已存爲草稿於"+mydate.toLocaleString()+"</p>");
        $("#tip").show();
        $("#tip").delay(5000).hide(0);
    });
});
</script>

這段代碼的主體能夠抽象成以下形式:java

 

[javascript] view plain copy
print ?
  1. <script>  
  2. $("#saveDraft").click(function(){});  
  3. </script>  
<script>
$("#saveDraft").click(function(){});
</script>
在上面的表單中,能夠看到咱們建立了一個id爲saveDraft的按鈕,所以這裏能夠經過$("#saveDraft")來訪問此按鈕,而且指定當單擊該按鈕時執行這個匿名function。

在這個匿名function中,咱們能夠經過blogContent = CKEDITOR.instances.id_content.getData();來取得當前CKeditor編輯器中的內容,並經過POST的方式將表單內容發送給服務器。在這裏,咱們使用jquery ajax的$.post方法來提交表單。該方法包括三個參數:url,data和callback函數。url即爲表單要提交到的地址,這裏咱們依然可使用Django提供的{% url %}標記做爲url;而data是咱們要提交的數據。與通常的提交表單相比,這裏的數據須要以json的格式發送給服務器;而callback是回調函數,即當表單內容被髮送給服務器後要執行的程序,這裏咱們會顯示存爲草稿的時間,而且顯示5秒後消失。python

定時存儲爲草稿的功能與這段代碼基本徹底同樣,只是把這個匿名函數加了個saveDraft的名稱,而後加上了setInterval(saveDraft,60000);這句,以便每隔60s便調用一次此函數,將文章存爲草稿,以下所示:jquery

在成功發佈博客後,頁面會跳轉到addblogResult.html頁面中,該頁面比較簡單,代碼以下所示:ajax

 

  1. {% extends "blogTemplate.html" %}  
  2. {% block content %}  
  3. <div class="content">  
  4. {{ info }}  
  5. </div>  
  6. <p><a href="{% url 'index' %}">返回首頁</a></p>  
  7. {% endblock %}  
{% extends "blogTemplate.html" %}
{% block content %}
<div class="content">
{{ info }}
</div>
<p><a href="{% url 'index' %}">返回首頁</a></p>
{% endblock %}

如今,咱們已經能夠發佈本身的博客了。下面讓咱們看看如何發佈評論。首先仍是先來看後端部分,咱們編寫了saveComment函數用於發佈評論,以下所示:json

 

[python] view plain copy
print ?
  1. # blogs/views.py  
  2. # ...  
  3. def saveComment(request):  
  4.     comment_content = request.POST['blogcomment']  
  5.     blog = Blog.objects.get(pk=request.session['currblogId'])  
  6.     result_info = ''  
  7.     try:  
  8.         auther = Users.objects.get(username=request.session['username'])  
  9.     except KeyError:  
  10.         auther = Users.objects.get(username='anony')  
  11.     try:  
  12.         mycomment = Comment.create(blog,comment_content,auther,datetime.datetime.now())  
  13.         blog.commentcount = blog.commentcount + 1  
  14.         blog.save()  
  15.         mycomment.save()  
  16.         result_info = 'Success'  
  17.     except ValidationError as e:  
  18.         result_info = 'Fail'  
  19.     return HttpResponseRedirect(reverse('blogs:content',kwargs={'blogId':request.session['currblogId']}))  
  20. # ...  
# blogs/views.py
# ...
def saveComment(request):
    comment_content = request.POST['blogcomment']
    blog = Blog.objects.get(pk=request.session['currblogId'])
    result_info = ''
    try:
        auther = Users.objects.get(username=request.session['username'])
    except KeyError:
        auther = Users.objects.get(username='anony')
    try:
        mycomment = Comment.create(blog,comment_content,auther,datetime.datetime.now())
        blog.commentcount = blog.commentcount + 1
        blog.save()
        mycomment.save()
        result_info = 'Success'
    except ValidationError as e:
        result_info = 'Fail'
    return HttpResponseRedirect(reverse('blogs:content',kwargs={'blogId':request.session['currblogId']}))
# ...

這段程序和Users App中的登陸程序有類似的地方,都是經過request.POST的方式取得表單的數據,而後進行後續操做。與發佈博客不一樣的是,這裏使用了Comment Model中創建的create函數來創建新的Comment數據,經過create函數,咱們能夠更加靈活地決定Model中每一個字段的值。還需注意的一點是,在成功發佈評論後,咱們並無跳轉到一個新的頁面,而是仍然跳轉到當前瀏覽的博客的頁面,所以咱們能夠馬上看到咱們發佈的評論:

而發佈評論的前端部分在上一篇博客中介紹content頁面的部分中已經包括了,這裏再搬運一下:後端

 

  1. <!-- blogs/templates/blogs/content.html -->    
  2. {% extends "blogTemplate.html" %}    
  3. {% block content %}    
  4. <div class="content">    
  5. <h2>{{ blog_title }}</h2>    
  6. {{ content|safe }}    
  7. </div>    
  8. <p><a href="{% url 'index' %}">返回首頁</a></p>    
  9. {% endblock %}    
  10. {% block comment %}    
  11. {% if comment_list %}    
  12.         
  13.     {% for comment in comment_list %}    
  14.         <ul class="comment">    
  15.         <li>    
  16.         {% if comment.auther.username == "anony" %}    
  17.         <h4>匿名用戶    {{ comment.createtime|date:"Y-m-d H:i:s" }}</h4>    
  18.         {% else %}    
  19.                 <img src="{{ comment.auther.logoimage.url }}" width="64" height="64" />    
  20.         <h4>{{ comment.auther }}    {{ comment.createtime|date:"Y-m-d H:i:s" }}</h4>    
  21.         {% endif %}    
  22.         </li>    
  23.         <li>{{ comment.content|safe }}</li>    
  24.         </ul>    
  25.         <hr/>    
  26.     {% endfor %}    
  27. {% else %}    
  28.     <ul class="comment">    
  29.     <p>尚未人發表評論</p>    
  30.     </ul>    
  31. {% endif %}    
  32. <span>評論 </span>    
  33. <form action="{% url 'blogs:saveComment' %}" method="post">    
  34. {% csrf_token %}    
  35. <ul class="comment">    
  36. <li><textarea name="blogcomment"></textarea></li>    
  37. <li><input type="submit" value="提交"></li>    
  38. </ul>    
  39. </form>    
  40. {% endblock %}   
<!-- blogs/templates/blogs/content.html -->  
{% extends "blogTemplate.html" %}  
{% block content %}  
<div class="content">  
<h2>{{ blog_title }}</h2>  
{{ content|safe }}  
</div>  
<p><a href="{% url 'index' %}">返回首頁</a></p>  
{% endblock %}  
{% block comment %}  
{% if comment_list %}  
      
    {% for comment in comment_list %}  
        <ul class="comment">  
        <li>  
        {% if comment.auther.username == "anony" %}  
        <h4>匿名用戶    {{ comment.createtime|date:"Y-m-d H:i:s" }}</h4>  
        {% else %}  
                <img src="{{ comment.auther.logoimage.url }}" width="64" height="64" />  
        <h4>{{ comment.auther }}    {{ comment.createtime|date:"Y-m-d H:i:s" }}</h4>  
        {% endif %}  
        </li>  
        <li>{{ comment.content|safe }}</li>  
        </ul>  
        <hr/>  
    {% endfor %}  
{% else %}  
    <ul class="comment">  
    <p>尚未人發表評論</p>  
    </ul>  
{% endif %}  
<span>評論 </span>  
<form action="{% url 'blogs:saveComment' %}" method="post">  
{% csrf_token %}  
<ul class="comment">  
<li><textarea name="blogcomment"></textarea></li>  
<li><input type="submit" value="提交"></li>  
</ul>  
</form>  
{% endblock %} 
這段代碼中最下方的表單就是咱們發佈評論所用到的。因爲Comment Model沒有涉及文件的上傳操做,所以咱們沒有采用ModelForm的形式,而是本身在前端組織表單,並將對應的值發送給後端。對於一些不太複雜的Model,採用本身設計的表單可能會更方便。 截止到這篇博客,Users App和Blogs App的核心功能已經完成了,咱們如今實現的功能有:用戶註冊、用戶登陸、退出登陸、查看用戶資料、發佈博客、將博客存爲草稿、發佈評論以及瀏覽博客等。從下篇博客開始,將會繼續開發與Users App和Blogs App相關的管理功能,包括編輯博客、刪除博客、修改用戶信息等功能,但願你們繼續關注~
相關文章
相關標籤/搜索