首先還是貼一下源代碼地址 https://github.com/goodspeedcheng/sblog
上一篇文章我們介紹了靜態文件使用以及如何使用from實現對blog的增刪改,這篇將介紹如何給blog添加評論模塊
1、添加comments庫
comments庫是是django框架內置的一個評論庫,可以快速的搭建岀一個評論系統,不過再自定義方面有些麻煩,不想用的話也可以自己動手編寫
comments 文檔地址 https://docs.djangoproject.com/en/1.4/ref/contrib/comments/
激活comments方法
- 在setting.py INSTALLED_APP 添加 'django.contrib.comments',
- 更新數據庫 :執行 python manage.py syncdb
- 添加comments url到項目urls.py
urlpatterns = patterns('', ... (r'^comments/', include('django.contrib.comments.urls')), ... )
在templates 中使用 comment template tags
因為settings.py中的INSTALLED_APPS中的django.contrib.sites我們早已取消注釋,現在打開 admin 就能管理評論了
2、在模板中使用comments
導入自定義標簽即可。
{% load comments %}
# 統計評論數量 {% get_comment_count for blog as comment_count %} <p>This event has {{ comment_count }} comments.</p> # 顯示評論 默認comments/list.html 模板 {% render_comment_list for event %} # 自定義顯示評論列表 {% get_comment_list for [object] as [varname] %} 例如 {% get_comment_list for event as comment_list %} {% for comment in comment_list %} ... {% endfor %} # 顯示評論提交表單 {% get_comment_form for blog as form %} <table> <form action="{% comment_form_target %}" method="post"> {% csrf_token %} {{ form }} <tr> <td colspan="2"> <input type="submit" name="submit" value="Post"> <input type="submit" name="preview" value="Preview"> </td> </tr> </form> </table>
這些都是comments庫內置的一些方法和屬性,有些可以直接使用,但是comments表單不是我們想要,我們要按自己的要求來
3、自定義評論表單
首先上代碼

1 {% block comments %} 2 <article id="cmt"> 3 {% get_comment_count for blog as comment_count %} 4 <h4 class="muted comtop">{{ comment_count }} Comments</h4> 5 <hr class="soften"> 6 {% get_comment_list for blog as blog_com %} 7 {% for comment in blog_com %} 8 <div class="container-fluid none-padding"> 9 <p class="muted"><small>{{ comment.user }}</small><small>{{ comment.submit_date|date:"F,j,Y" }}</small></p> 10 {{ comment.comment }} 11 </div> 12 <hr class="soften"> 13 {% endfor %} 14 </article> 15 16 <article > 17 {% get_comment_form for blog as blog_form %} 18 <div id="comment_form"> 19 <h4 class="muted comtop">New Comments</h4> 20 <form class="form-horizontal" action="{% comment_form_target %}" method="post"> 21 <fieldset> 22 {% csrf_token %} 23 {{ blog_form.object_pk }} 24 {{ blog_form.content_type }} 25 {{ blog_form.timestamp }} 26 {{ blog_form.site }} 27 {{ blog_form.submit_date }} 28 {{ blog_form.security_hash }} 29 <div class="control-group"> 30 <label class="control-label" for="id_name">name: </label> 31 <div class="controls"> 32 <input type="text" id="id_name" class="input-xlarge" name="name" placeholder="please enter name" required="required"> 33 </div> 34 </div> 35 <div class="control-group"> 36 <label class="control-label" for="id_email">email: </label> 37 <div class="controls"> 38 <input class="input-xlarge" id="id_email" type="email" name="email" placeholder="please enter email" required="required"> 39 </div> 40 </div> 41 <div class="control-group"> 42 <label class="control-label" for="id_comment">comment: </label> 43 <div class="controls"> 44 <textarea class="input-xlarge comment" id="id_comment" name="comment" placeholder="please enter comment" required="required"></textarea> 45 </div> 46 </div> 47 <p style="display:none;"><label for="id_honeypot">如果你在該字段中輸入任何內容,那么你的評論就會被視為垃圾評論。</label> <input type="text" name="honeypot" id="id_honeypot"></p> 48 <div class="form-actions"> 49 <input class="btn btn-info" type="submit" name="submit" value="Post"> 50 {# <input class="btn btn-info" type="submit" name="preview" value="Preview"> #} 51 <input type='hidden' name='next' value='{% url detailblog blog.id %}'/> 52 </div> 53 </fieldset> 54 </form> 55 </div> 56 </article> 57 {% endblock %}
現在再打開博客頁面就會發現下面出現來自定義后的評論表單,但是我們現在提交會發現
CSRF verification failed. Request aborted.
解決方法: 只需要將views.py中 blog_show
return render_to_response("blog_show.html", {"blog": blog}) 改為 return render_to_response("blog_show.html", {"blog": blog}, context_instance=RequestContext(request))
現在是不是成功了呢
表單中包含字段:
- csrfmiddlewaretoken——django csrf中間件需要
- content_type—— 內容類型
- content_pk——ID值
- site—— 站點
- user—— 用戶對象
- timestamp——當前時間
- security_hash——安全檢測用
- name——名稱
- email——郵箱
- comment——內容
- submit_date——提交日期
- honeypot——防止機器亂填垃圾信息
現在我們來說一下自定義comments form的關鍵吧
- 自定義表單時,一定要加上{% csrf_token %}這句,因為comments 使用的是post方法
- 使用默認表但是,comments會自動把所有字段補齊,我們也應該這樣,否則會提交失敗
{{ blog_form.object_pk }} {{ blog_form.content_type }} {{ blog_form.timestamp }} {{ blog_form.site }} {{ blog_form.submit_date }} {{ blog_form.security_hash }}
honeypot字段是用於防止機器程序發布垃圾信息的。文檔里的說法是:一般機器程序發布垃圾信息時,會把表單里的所有字段都填上,而這個字段一旦被填上則此信息將被判為垃圾信息所以這個不能填寫
如果評論表單未提交成功,則comments庫會自動加載其源碼中的comments/preview.html這個默認模板,提醒用戶表單項有誤。但需要注意的是這個模板會很丑陋,故你可以在自己的項目中復制這個模板(路徑要保證是templates/comments/preview.html即可),重寫你自己的提醒內容,加上自己設計的樣式。
4、添加ajax支持
首先在blog_show.html添加
{% block script %} <script type="text/javascript" charset="utf-8"> function bindPostCommentHandler() { $('#comment_form form input.submit-preview').remove(); $('#comment_form form').submit(function() { $.ajax({ type: "POST", data: $('#comment_form form').serialize(), url: "{% comment_form_target %}", cache: false, dataType: "html", success: function(html, textStatus) { $('#cmt').replaceWith(html); $('#comment_form form')[0].reset(); }, error: function (XMLHttpRequest, textStatus, errorThrown) { $('#comment_form form').replaceWith('Your comment was unable to be posted at this time. We apologise for the inconvenience.'); } }); return false; }); } $(document).ready(function() { bindPostCommentHandler(); }); </script> {% endblock %}
首先定義 bindPostCommentHandler 方法
下一行移除 preview button
使用jquery ajax 方法以post形式提交數據 如果成功 將 cmt塊替換為 html 內容 並將form重置
return false 作用是禁用form 中action 方法
現在提交數據會發現#cmt 被完整的頁面替換掉了,這不是我們想要的結果
解決方法:
修改自定義表單中最后一行(這一行的作用是提交完表單后跳轉的頁面)
<input type='hidden' name='next' value='{% url detailblog blog.id %}'/>
為
<input type='hidden' name='next' value='{% url showcomment blog.id %}'/>
相應的在urls.py添加
url(r'^blog/(?P<id>\d+)/commentshow/$', 'blog_show_comment', name='showcomment'),
在views.py添加
def blog_show_comment(request, id=''): blog = Blog.objects.get(id=id) return render_to_response('blog_comments_show.html', {"blog": blog})
新建blog_comments_show.html 內容為
{% load comments %} <article id="cmt"> {% get_comment_count for blog as comment_count %} <h4 class="muted comtop">{{ comment_count }} Comments</h4> <hr class="soften"> {% get_comment_list for blog as blog_com %} {% for comment in blog_com %} <div class="container-fluid none-padding"> <p class="muted"><small>{{ comment.user }}</small><small>{{ comment.submit_date|date:"F,j,Y" }}</small></p> {{ comment.comment }} </div> <hr class="soften"> {% endfor %} </article>
現在刷新頁面提交評論是不是正常了呢
下一篇將介紹如何添加markdown代碼高亮
最后源代碼可以在 https://github.com/goodspeedcheng/sblog 可以看一下 希望大家把錯誤的地方提出糾正一下。
謝謝
擴展閱讀: https://docs.djangoproject.com/en/1.4/
參考博客:http://ca.rroll.net/2009/05/10/improving-django-comments-user-experience-with-ajax/
推薦 Django 最佳實踐 - 中文版 https://github.com/brantyoung/zh-django-best-practices/blob/master/readme.rst/
ps: 大四學生求實習 郵箱: cacique1103#gmail.com