django 简易博客开发 4 comments库使用及ajax支持
首先还是贴一下源代码地址 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
- urlpatterns = patterns('',
因为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即可),重写你自己的提醒内容,加上自己设计的样式。
- {{ blog_form.object_pk }}
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/
django 简易博客开发 1 安装、创建、配置、admin使用
http://www.cnblogs.com/cacique/archive/2012/09/29/2707976.html
django 简易博客开发 2 模板和数据查询
http://www.cnblogs.com/cacique/archive/2012/09/30/2709143.html
django 简易博客开发 3 静态文件、from 应用与自定义
http://www.cnblogs.com/cacique/archive/2012/10/01/2709668.html
django 简易博客开发 4 comments库使用及ajax支持
http://www.cnblogs.com/cacique/archive/2012/10/03/2710803.html
django 简易博客开发 5 markdown支持、代码高亮、gravatar头像服务
http://www.cnblogs.com/cacique/archive/2012/10/07/2713703.html
django 简易博客开发 4 comments库使用及ajax支持的更多相关文章
- django 简易博客开发 5 markdown支持、代码高亮、gravatar头像服务
上一篇博客介绍了comments库使用及ajax支持,现在blog已经具备了基本的功能,但是只能发表文字,不支持富文本编辑.今天我们利用markdown添加富文本支持. markdown语法说明: h ...
- django 简易博客开发 3 静态文件、from 应用与自定义
首先还是贴一下源代码地址 https://github.com/goodspeedcheng/sblog 上一篇博客我们介绍了 django 如何在views中使用templates以及一些常用的数 ...
- django 简易博客开发 2 模板和数据查询
首先还是贴一下项目地址 https://github.com/goodspeedcheng/sblog 因为代码全在上面 上一篇博客我们介绍了 django的安装配置,新建project,新建a ...
- django 简易博客开发 1 安装、创建、配置、admin使用
首先贴一下项目地址吧 https://github.com/goodspeedcheng/sblog 到现在位置项目实现的功能有: 1.后台管理使用Admin ,前端显示使用bootstrap 2. ...
- django 简易博客开发 1 安装、创建、配置、admin使用(转)
Django 自称是“最适合开发有限期的完美WEB框架”.本文参考<Django web开发指南>,快速搭建一个blog 出来,在中间涉及诸多知识点,这里不会详细说明,如果你是第一次接触D ...
- Django个人博客开发 | 前言
本渣渣不专注技术,只专注使用技术,不是一个资深的coder,是一个不折不扣的copier 1.前言 自学 Python,始于 Django 框架,Scrapy 框架,elasticsearch搜索引擎 ...
- 简易博客开发(8)----django1.9 博客部署到pythonanywhere上
准备工作 首先需要注册一下,pythonanywhere的免费账户有一定的限制,只能创建一个web app,不能绑定独立域名,不能通过ssh连接,不过只是搭一个project也是够用了. 注册成功之后 ...
- Django练习——博客系统小试
在上一篇博客Todolist的基础上(http://blog.csdn.net/hcx25909/article/details/24251427),本周继续进行实践,这次我要搭建一个简单的博客系统. ...
- Django搭建简易博客
Django简易博客,主要实现了以下功能 连接数据库 创建超级用户与后台管理 利用django-admin-bootstrap美化界面 template,view与动态URL 多说评论功能 Markd ...
随机推荐
- 封装addClass 、 removeClass
<script> window.onload = function() { var oDiv = document.getElementById('div1'); var oDiv2 = ...
- hdu6290 奢侈的旅行
最短路算法的复杂度考虑! 书上已经做了优化,用的是优先队列:用优先队列实现堆优化 V为点集,E为边集 从O(V^2)优化到O(ElogV) 然后再记忆一下inf 0x3f3f3f3f的十进制是1061 ...
- 通过JS加载XML文件,跨浏览器兼容
引言 通过JS加载XML文件,跨多种浏览器兼容. 在Chrome中,没有load方法,需要特殊处理! 解决方案 部分代码 try //Internet Explorer { xmlDoc=new Ac ...
- eclipse生成spring boot jar包
1.右击项目,选择Run As - Maven clean 2.右击项目,选择Run As - Maven install 3.成功后 会在项目的target文件夹下生成jar包 4.将打包好的jar ...
- Element UI tree 回显问题
Part.1 问题 写项目时遇到一个棘手的问题,在做关于权限功能时,点击修改需要显示角色原本对应的权限.涉及到了 tree 组件回显,但是有一个很尴尬的问题:tree 组件只要父节点选中,那么子节点就 ...
- 微信小程序---目录结构
(1)目录结构 小程序包含一个描述整体程序的 app 和多个描述各自页面的 page.一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下: (2)允许上传的文件 .
- 普通用户切换到root用户
普通用户切换到root用户首先按组合键 CTRL+ALT+T 进入终端界面,一般终端界面默认为普通用户权限模式,如何从普通用户进入root用户首先重置root密码输入 sudo passwd root ...
- 获得Dictionary所有key和value值
Dictionary<string, string> dc = new Dictionary<string, string>(); dc.Add("code" ...
- 解决浏览器自动填充input
浏览器输入框自动填充解决办法 emmmmm:今天处理公司后台系统遇到的:登录页面浏览器保存账号密码后:浏览器会自动在其他页面进行填充:解决如下图: 浏览器会默认填充input type值为passwo ...
- More Effective C++ - 章节二 : 操作符(operators)
5. 对定制的 "类型转换函数" 保持警觉 允许编译器执行隐式类型转换,害处多过好处,不要提供转换函数,除非你确定需要. class foo { foo(int a = 0, in ...