Extjs Django Adobe Air全用上 – SimpleLife开发小记(上)

周末闲来无事,加上心情不错,决心突破一下Extjs给我留下的心理障碍,过了这道坎。重新下载了extjs 2.2的文件包,然后开始狂搜入门文章,真的是太少了。然后开始找几个看起来比较顺眼的demo,猛看源代码。

要上手当然要有个程序来下手,前两天简单做过的关于Getting Things Done的那个工作任务管理程序真是再适合不过了,功能简单,貌似有用,界面少,却可以独立成站,而且已经有了成型的思路(甚至成型的程序),上手要容易很多,只要把精力关注于Extjs上面就可以了。

进入开发环境,用现成的项目复制出一套Django的运行环境,把用户注册登录和任务管理的部分复制过来,稍微改点配置,建立数据库,运行测试服务器,OK,可以跑起来了。

然后把extjs的js文件,css文件和图片文件复制过来,正式开工。

 

继续阅读“Extjs Django Adobe Air全用上 – SimpleLife开发小记(上)”

Extjs Django Adobe Air全用上 – SimpleLife开发小记(下)

Extjs版的SimpleLife靠一段落,接下来要攻克的就是Adobe Air了。这个东西出来的时间已经很长了,前面看它的开发方式一直云里雾里,下手似乎有些困难,但是唯一的印象就是,通过AIR可以直接把HTML和JS写的网站包装成客户端程序来运行。既然如此,那用Extjs的富客户端方式写的网站岂不是可以直接移植成客户端程序?果然有如此好事?

于是,又是一番疯狂搜索,看了一些AIR的入门文章,写了一个HelloWorld的网页,根据网上的说明,建个目录,写个application.xml的起始文件,下载了AIR SDK,无需安装,解压后直接把bin目录配置到系统环境变量的Path里面去,在命令行窗口里进入网页所在目录,运行adl application.xml,哇,果然很帅啊。

接下来,把SimpleLife里面的index.html(整个网站就这么一个html文件),以及用到的Extjs相关的文件全部拷过来,把js里面读写数据涉及到的URL全部加上域名变成绝对路径,再启动,哇塞,真的可以启动起来啊!

 

继续阅读“Extjs Django Adobe Air全用上 – SimpleLife开发小记(下)”

一个不错的架构设计

Django马上就要发布1.0正式版了,等了好几年,现在才准备要出来。(看官方网站上应该就是这两天了)。在接近正式版的Beta2上,官方的介绍里重点强调了一个模块,comments,于是去读了一下它的文档,果然是个好东西啊。

简言之,comments是一个用于给任何对象添加用户回复功能的模块。你只要在配置文件里加上这个app,在html模板里加上一个load的调用,马上就可以给你原来的对象添加回复功能。所有的回复都存储在它自己的表里。取回复数,显示回复列表,显示回复文本框都有现成的方法可以调用,而发表回复的过程则是全自动处理的。

看完文档的第一感觉是这个模块设计的非常巧妙,你原来的所有的model,比如文章,用户,相片,或者理财易里面的账本,收支,预算等等,全部都可以很方便的增加用户评论的功能。(当然,对于喜欢挑刺的我来说,还有一个第一感觉,它的效率可能会差一点,因为在不修改原对象的情况下,它没有办法把每个对象的评论数放到原对象的表里,而只能在显示每条对象的时候去它自己的表里取一次数据。这样如果在显示某个List的时候想显示评论数,就会造成大量的数据库读取。)

但是,瑕不掩瑜,这个模块的设计理念是一流的,如果海内有这样的设计,就不会需要花那么久的时间才能给迷你博客加上评论功能了。(如果把它设计的不那么灵活,通过它来维护对象所在表中的回复数也是很容易的事。)

Django的自定义filter陷阱

Django的filter提供在HTML模板中格式化内容的功能,比如用来格式化大段的文本,或者格式化时间和数字的显示,对我来说,主要是用在循环里面对数据做处理,尤其是取出来的不是model的时候。(如果是model,就可以在model里定义实例方法直接在模板里面调用了)。

但是直到今天,才发现了Django的自定义filter的处理方式的一个重要Bug。

实现自定义filter的方法,是在某个app(任意一个)目录下增加一个templatetags,并在它下面增加__init__.py把它变成一个包。然后在该目录下增加任意的py文件,在里面写自己的处理函数就可以了,然后把函数注册成filter,就可以在任意的html模板里面使用了。

本来这种用法已经用了很久,一直没什么问题,而且在多个项目里面都是这样用的。这多个项目运行在同一台机器上,使用lighttpd+fastcgi方式来运行。

今天在给一个tags文件里添加了两个函数以后,在本地测试都没有问题了,结果传到服务器上打开那个页面,却提示新加的那个filter不存在,invalid filter。找来找去找不到问题,后来只想到一个结果:多个不同的项目里面同名的自定义filter文件会冲突。配置文件里面找了几圈也没找到限定加载templatetags的路径的地方。但是使用fastcgi方式的话,每个项目使用自己的manage.py runfcgi方式来运行,各自使用独立的内存空间,怎么会跑去加载别人的filter文件呢?

后来在limodo的网站上看到了一句话,说django的load filter文件的语法是没有项目限定符的,同名的文件只会加载一个,所以他加了个patch,允许在load的时候加上项目限定名。不过这样处理有点麻烦了,我还是用个简单的方法吧。把topic_function.py改成licaie_topic_function.py,所有该项目里面用到的地方都改掉,上传到服务器测试,OK了。

我至今也没有相通,在fastcgi模式下,而且它们并不知道别的项目的物理位置,怎么会出现这样的一个冲突呢?目前还是因为新函数报错,比较容易看到错误,而如果是同名函数但是功能不同,那就更麻烦了,也许跑上半月你都还不知道这里有个错误。

Django的服务器选择

在Django官方的配置文档上,建议的生产环境服务器是Apache+Mod_Python,同时也说明了Lighttpd+FastCGI是个不错的选择,有时还可以提供更好的性能。

对于性能问题,许多用户有着完全不同的意见,在一份比较可信的报告上,使用最精简的Apache编译,配合Mod_Python模块运行Django,跟Lighttpd+FastCGI的方案相比,在单用户并发的情况下,性能稍弱,但是在10并发和100并发的情况下,性能要高出40%左右。

当然,通常情况下你的Apache不可能是最精简状态,Apache的性能会随着加载模块的数量逐步降低。(当然,你可以为每一种不同的应用编译一个Apache实例,虽然比较麻烦,但是的确是个好的选择)而Lighttpd本身是轻量的,功能的多少对性能影响不大。而且随着并发量的上升,Apache的进程模式对系统资源占用很厉害,所以对于硬件资源有限的平台,Lighttpd应该是个更好的选择。

另外还有一个重要的要考虑的问题,你的服务器是否只运行Python?以我个人的经验,Apache在同时加载了Mod_Python和php模块的话,Python的某些函数会出现奇怪的结果。但是如果没有php模块,就不会出现这个问题。这个问题被人称为“Linux上的dll黑洞”,不同的模块如果使用到了不同版本的外部项目,那么它们就会产生影响。在CGI模式则不会,所有的模块都是完全独立的。所以如果需要同时运行Django和PHP程序,那么两者不能同时使用Apache的模块方式,至少有一个要使用CGI模式(或者分别编译到两个Apache实例上)。

PS:据说另一个新的小型WEB服务器Ngnix也不错,其性能和资源消耗都跟Lighttpd差不多,美国的许多空间提供商使用了这个服务器,在同样的硬件平台上,甚至可以提供Apache 10倍的负载能力,而且,它可以在不间断服务的情况下进行软件升级,Apache的Rewrite规则也可以在很少修改的情况下直接拿来使用,都是不错的选择。