首先还是贴一下源代码地址 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