月度归档:2012年08月

[django-ajax-validation]Django表单AJAX校验及提交的APP

项目地址https://github.com/vicalloy/django-ajax-validation
django-ajax-validation是一个使Django支持表单AJAX校验的第三方APP。我做了一些修改,增加了表单的AJAX提交以及twitter-bootstrap的支持。

安装

  • pip install git+git://github.com/vicalloy/django-ajax-validation.git
  • 在Django settings的INSTALLED_APPS中加上”ajax_validation”。

一个简单的使用范例

views.py

from ajax_validation.views import validate_form
from ajax_validation.utils import render_json_response
...
class TimelineForm(forms.ModelForm):
    class Meta:
        model = Book
def add_book(request):
    #创建表单并进行校验。返回表单以及校验结果。
    form, validate = validate_form(request, form_class=BookForm)
    if validate['valid']:#如果校验成功,执行保持操作
        book = form.save()
    return render_json_response(validate)//返回JSON

模板

进阶

django-ajax-validation的原始文档就写的非常糟糕,我也偷懒,所以想了解更多还是直接看代码吧。

Node.js相关知识

简单的说Node.js是一个使用Javascript作为开发语言的web开发框架。凭借JS良好的用户基础以及Node.js的高性能等优势Node.js迅速的流行了起来。
此前我一直以为Node.js只是一个使用JS作为开发语言的类ROR开发框架。在对Node.js做过简单的了解后发现这确实是一个很酷的东西。如果有机会非常希望将系统的部分功能改由Node.js实现。
由于Node.js的资料已经不少,这里就不再多费唇舌。想对Node.js有更多了解可以参考下面的一些文档。

  • Node.js 究竟是什么 让你对哦Node.js有个总体概念。Node.js是什么,适合做什么,不适合做什么。
  • Node入门 一本(篇)免费的Node.js入门教程。可以用于了解Node.js一些基础使用以及相关概念。
  • Node.js官方文档(API文档) 可以看前几节,对Node.js的Global Objects有些了解。其他的东西可以用的时候再查。
  • 深入浅出Node.js InfoQ关于Node.js的系列文章。
  • Node Club@GitHub Node Club 是用 Node.js 和 MongoDB 开发的新型社区软件。这是一个开源项目,可以用于熟悉Node.js。简单的阅读过Node Club的代码,感觉用Node.js做传统WEB开发的体验并不是太好。
  • npm Node.js使用的包管理工具。在这里你可以找到很多优秀的JS库。很多JS库不但可以用于Node.js还可以直接用于前端。Node.js的社区非常活跃,第三方库的增长速度非常的快。在这些第三方库中不乏一些很有创意的东西。
    • express 构建在Node.js之上的WEB开发框架。
    • lesscoffee-script 这两个已经太出名了
    • jade 非常酷的一个JS模板语言,看上去有些类似zenCODE。
    • ejs 另一个JS模板语言。相比jade,ejs更适合普通人的使用习惯。
#jade
html
  body
    h1 User <em>#{name}</em>

题外话(About WebSocket&Django)
WebSocket的良好支持是Node.js的一大优势。WebSocket是HTML5里出来的新东西。WebSocket的实质是在浏览器与服务器间建立一个socket连接从而实现客户端与服务端的双向通信。由于Python的WSGI协议无法支持WebSocket,所以包括Django在内的大多WEB框架要支持WebSocket并不是一件容易的事(注:Evented Django这篇文章里有介绍如何使Django支持WebSocket,不过总的来说有些折腾)。Tornado和Node.js一样同为非阻塞的WEB服务框架不需要使用到WSGI,所以不存在这个问题。

web服务器的同步与异步

最近几年node.js和tornado的流行和他们采用的是非阻塞(异步)模式有很大的关系。传统的web服务器通常采用的是同步方式,服务器的每个进程/线程每次只能处理一个请求,在遇到高并发的情况时为即使处理请求必须创建足够多的进程/线程来处理每个请求。举个简单的例子,如果每个请求的处理时间为4秒,为了支持每秒100次请求,你必须为此创建4*100个进程。创建400个进程,这个成本无疑是有些太高了。
node.js和tornado等异步服务器在接收到用户请求后,先将请求放到后台处理,等处理完成后再处理结果返回给用户。node.js和tornado都采用了类似的事件机制,可以在一个进程里并行的处理多个用户请求。在遇到高并发的情况下不需要创建多个进程/线程就可以轻松应对。也真是因此许多人认为异步模式肯定比同步模式要强,异步模式肯定要更好。
Gunicorn是一个Python WSGI HTTP服务器,同时支持同步以及异步模式。Gunicorn默认采用的是同步模式,在它的Design一节中有关于同步以及异步模式的选择说明。前面讲到同步模式下为处理高并发需要创建大量的进程,但如果每次请求的处理时间都非常短就不会出现需要创建大量进程的情况。如前面的例子中,如果每次请求的处理时间为0.1秒,则只要创建0.1×100个进程即可支持每秒100次的请求。node.js、tornado的事件机制虽然要比创建进程和线程的成本要低的多,但也不是完全没有开销的。
最后总结下:
如果服务满足一下特点时可以考虑异步服务器,不然就不是很有必要了

  • 大量的并发请求
  • 每个请求处理的耗时都比较长

将LBForum、“似水流年”的部署环境切换到Gunicorn+Supervisor

Gunicorn 是一个Python WSGI UNIX的HTTP服务器。Gunicorn有着不错的性能以及稳定性。Gunicorn对WSGI、Django、Paster提供了很好的支持,使用起来非常的简单。
此前 LBForum似水流年 使用apache+wsgi的方式部署在webfaction上。为了给服务器节约些内存将部署方式切换到Gunicorn。不过似乎效果并不明显。除工作进程外,Gunicorn还会另外启动一个master进程用于管理子进程。master进程加一个子进程的内存耗用量加在一起大概在40M左右。
注:在一些评测里Gunicorn的性能并不是太好。Gunicorn支持多种 worker-class ,默认的worker-class使用的是同步模式。在将worker-class切换到gevent或tornado性能会好出不少。

DPress部署到SAE

将DPress部署到SAE的简要说明。如果你在部署过程中有遇到什么问题,欢迎反馈。

  • 在SAE管理后台创建应用,开发语言选择python
  • 使用svn将应用代码更新到本地
  • 修改配置文件config.yaml
name: 你的应用名称
version: 1
libraries:
- name: django
  version: "1.4"
  • 将DPress sites目录下所有文件复制到SAE应用目录(如:dpress/1/)。
  • 在应用的根目录下创建目录libs(如:dpress/1/libs/)
  • 将virtualenv.bundle.zip复制到libs目录
  • 在服务管理中启用mysql数据库
  • 由于SAE上无法使用Django命令。需要在本地使用syncdb命令在本地mysql数据库中创建好DPress的初始数据,然后使用SAE的phpmyadmin将数据导入到SAE。
  • 在服务管理中创建Storage,并将Domain设置为base
  • 创建配置文件settings/local.py
# -*- coding: UTF-8 -*-
import sae.const
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': sae.const.MYSQL_DB,                      # Or path to database file if using sqlite3.
        'USER': sae.const.MYSQL_USER,                      # Not used with sqlite3.
        'PASSWORD': sae.const.MYSQL_PASS,                  # Not used with sqlite3.
        'HOST': sae.const.MYSQL_HOST,                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': sae.const.MYSQL_PORT,                      # Set to empty string for default. Not used with sqlite3.
    }
}
DEFAULT_FILE_STORAGE = 'saestorage.SaeStorage'
FILEBROWSER_DIRECTORY = ''
STATIC_URL = 'http://vicalloy.sinaapp.com/dpress/'#修改为你静态资源位置
DPRESS_TITLE = u'天地一沙鸥'
DPRESS_SUBTITLE = u'to be continue'
DPRESS_DESCN = ''
DISQUS_SHORTNAME = ''
GOOGLE_ANALYTICS_CODE = ''
#根据你的静态资源位置进行修改
EPIC_JS = 'http://vicalloy.sinaapp.com/dpress/dpress/epiceditor/js/epiceditor.min.js'
EPIC_BASEPATH = 'http://vicalloy.sinaapp.com/dpress/dpress/epiceditor'

  • 到这里服务已经可以跑起来了。由于没有对静态资源进行配置,将出现无法找到静态资源的情况。
  • 创建一个新的SAE应用,应用类型选择PHP,专门用于管理DPress的静态资源文件(如:dstatic.sinaapp.com)。
  • 在本地运行Django的collectestatic命令将DPress的静态资源收集到sites/collectedstatc/目录。
  • 将collectedstatc中的内容复制到新创建的站点
    • 如:static/dpress/。对应的STATIC_URL配置文件修改为 http://dstatic.sinaapp.com/static/dpress/

DPress配置、定制、模板创建指南

DPress项目地址: https://github.com/vicalloy/DPress
DPress是我用Django写的一个博客系统,支持使用MarkDown语法进行博客的书写。这里将就系统的配置,模板定制修改,以及如何创建自己的模板给个简要的指南。由于系统使用Django开发,使用者最好能有一定的Django基础。

使用Django的开发服务器将系统跑起来

  • clone DPress的代码库(git://github.com/vicalloy/DPress.git)
  • 运行scripts/create_env.py,该脚本将为你创建python虚拟环境,并自动安装相关依赖包。
  • 执行scripts/env.bat(. scripts/env.rc),进入刚创建的python虚拟环境。
  • %mg%($mg in linux) 是 “python manage.py ” 的快捷方式,用于方便的执行Django命令。
  • %mg% syncdb
  • %mg% migrate
  • %mg% runserver
  • DPress Admin http://127.0.0.1:8000/admin/
  • DPress http://127.0.0.1:8000/

配置

  • 复制 sites /settings/pre.samplepre.py 。修改其中的SETTINGS设置,确定使用哪个配置(默认可选production/dev)。
  • 复制 sites /settings/local.samplelocal.py 。并修改相关配置。
  • DISQUS_SHORTNAME以及GOOGLE_ANALYTICS_CODE这两个参数需要在正确设置后,DISQUS的评论功能以及GOOGLE ANALYTICS才可正常生效使用。

模板的配置与修改

  • DPress自带的模板在 sites/dpress/templates/ 目录。自定义模板放在 sites/templates/ 目录。系统将自动优先使用自定义模板目录的模板,实现对模板的重写。
  • dpress/include/footer.html 为页面的底部。可重写该文件,修改版权增加定义链接等。
  • dpress/include/sidebar.html 页面的侧边栏。重写该文件对侧边栏内容进行配置。
  • dpress/widgets/ 该目录为侧边栏小工具的模板。如果你需要创建自定义的侧边栏工具,请遵守约定将小工具模板放到该目录。
  • dpress自带的静态资源文件放在 sites /dpress/static/ 目录。自定义的静态资源文件放在 sites/static/ 目录。
  • 静态资源目录中 /dpress/themes/ 为主题目录。当前的默认主题为 default 。你可创建一个新文件夹用于存放你的新主题。
  • 重写 dpress/include/base_style.html 使用新主题的css文件。

SAE Storage for Django

DPress 修正后想着要部署一个在线的演示程序。问题是我自己虚拟主机的资源已经捉襟见肘,于是只能打SAE的主意了。
为保证文件上传功能的正常使用需要将Django默认的Storage实现替换为SAE的storage实现。SAE的官方并没有提供Django的storage实现,需要自己另外实现。在github:gist上有人贴出了SAE Storage for Django的实现(SAE Storage for Django)。github:gist上的这个SAE Storage实现有些bug,我修正后的版本见saestorage
注:

  • SAE Storage单节点的最大容量为2G(注:SAE Storage 服务限制)。这对于一些小站点来说是没什么问题,但如果是一个大型的商业站点这必然会有些不便。难道你需要配置一个storage列表,让程序自行去寻找可用的storage?
  • SAE Storage似乎不太稳定,上传的文件经常会打不开。

“DPress”原地满血复活

GitHub地址: DPress(GitHub)
演示地址: DPress(SAE)

DPress 是我在2009用django写的一个博客系统。此后年久失修,已经跑不起来了。
这两天花了些时间将项目重新修整一下,现在项目又可以重新跑起来了。功能方面新版的DPress有了些变化。

  • 提供对 Markdown 的支持(也只支持Markdown)。
  • 使用 EpicEditor 实现Markdown的实时预览。
  • 使用 DISQUS 实现文章的评论功能。(注:既然已经有了这么好用的评论服务,为什么还要自己写代码呢)
  • 支持代码高亮度。相关的语法说明见:Fenced Code Blocks
  • 支持Tag
  • 支持RSS
  • 使用 Django FileBrowser 提供文件上传的支持。
  • 使用 flatpages 提供对About等自定义页面的管理。
  • 内置GOOGLE ANALYTICS的支持
  • 代码量非常的小
  • 模板和代码分离的比较清晰,要创建一套自己的模板会是一件比较容易的事。

已知bug:直接从网页复制文本时EpicEditor的编辑框内会自动的添加一些看不见的html标签,将导致文本显示不正常。需要粘贴文本时最好先将文本粘贴到写字板中,再重新复制粘贴。

《旁观者》杂感

豆瓣链接: 《旁观者》
这书看完已经有段时间了,一直想写点什么却又憋不出几个字,还是随便写写吧。

两次世界大战

相比物质的破坏,世界大战对人类精神世界的破坏要更为彻底。在20世纪初,社会主义也曾是社会主流思想的一部分。在世界大战中,无数的社会精英消失在了战火中。本该发生的很多社会主义尝试也并未发生。纳粹主义作为国家社会主义的一种,想必也伤透了广大人民的心。社会主义并不是没有过机会,太多劣迹斑斑的历史让自己失去了机会。

战火之后的世界

在第二次世界大战后,几乎没有人相信这个世界会变好。二战后的一段时间却是全球经济发展最快的一段时间。战后的世界就如被野火焚烧过的草原,一个新的轮回即将开始。
所谓的乱世正是思想最为活跃的时期。面对多如乱麻的问题,众多的天才人物都试图去寻找一个有效的解决方案。这些理论在不断的碰撞过程中逐步完善,只要一有机会就将发光。
乱世是一个思想成型的过程,治世这是乱世产生的思想体系应用并完善的过程。战后的繁荣,在一定程度上是受着战争的馈赠。

真假弗洛伊德

弗洛伊德口中的自己和公众眼中的弗洛伊德有很大的不同。弗洛伊德说自己家境贫寒,实际上他一直生活安逸。弗洛伊德说自己被忽视,实际上不管他的观点一直都被重视,学术接在想法设法的驳斥他的观点。弗洛伊德说自己犹太人的身份给自己带来了很多麻烦,这也并不是事实。
弗洛伊德的现实与他自己的说法严重的不一致,源于他内心的不一致。有些谎言是用来骗别人,有些则是用来骗自己,骗着骗着自己就真的相信了。现代社会有着太多的压力,在压力无法以正常的途径得到排解时,就会以一些让人匪夷所思的方式继续释放。
创业者再向别人推销想法时将未来描绘的天花乱坠,或许他也清楚这个想法还存在很多问题,但如果自己不先说服自己又如何说服别人。有时候前进的步伐太慢,告诉自己慢不是问题,只要向着正确的方向走一定可以到达目标。慢是一个让人无法面对的事实,于是只能忽略。狐狸吃不到葡萄,于是告诉自己葡萄是酸的,从此葡萄就是酸的。