<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>非鱼观点 - 互联网观察 - Django</title>
    <link>http://www.unfish.net/</link>
    <description>子非鱼，安知鱼之乐？</description>
    <dc:language>cn</dc:language>
    <generator>Serendipity 1.3.1 - http://www.s9y.org/</generator>
    <pubDate>Thu, 04 Sep 2008 01:22:40 GMT</pubDate>

    <image>
        <url>http://www.unfish.net/allfiles/myphotos/logo.png</url>
        <title>RSS: 非鱼观点 - 互联网观察 - Django - 子非鱼，安知鱼之乐？</title>
        <link>http://www.unfish.net/</link>
        <width>169</width>
        <height>61</height>
    </image>

<item>
    <title>Django 1.0正式发布了</title>
    <link>http://www.unfish.net/archives/330-20080904.html</link>
            <category>Django</category>
    
    <comments>http://www.unfish.net/archives/330-20080904.html#comments</comments>
    <wfw:comment>http://www.unfish.net/wfwcomment.php?cid=330</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.unfish.net/rss.php?version=2.0&amp;type=comments&amp;cid=330</wfw:commentRss>
    

    <author>nospam@example.com (非鱼)</author>
    <content:encoded>
    
&lt;p&gt;下载：&lt;a onclick=&quot;javascript:urchinTracker(&#039;/extlink/www.djangoproject.com/download/&#039;);&quot; href=&quot;http://www.djangoproject.com/download/&quot; target=&quot;_blank&quot;&gt;http://www.djangoproject.com/download/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;如果你还在使用0.96及其以前的版本，务必先读一下不兼容列表：&lt;a onclick=&quot;javascript:urchinTracker(&#039;/extlink/code.djangoproject.com/wiki/BackwardsIncompatibleChanges&#039;);&quot; href=&quot;http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges&quot; target=&quot;_blank&quot;&gt;http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges&lt;/a&gt;&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Thu, 04 Sep 2008 08:55:12 +0800</pubDate>
    <guid isPermaLink="false">http://www.unfish.net/archives/330-20080904.html</guid>
    
</item>
<item>
    <title>一个不错的架构设计</title>
    <link>http://www.unfish.net/archives/329-20080902.html</link>
            <category>Django</category>
    
    <comments>http://www.unfish.net/archives/329-20080902.html#comments</comments>
    <wfw:comment>http://www.unfish.net/wfwcomment.php?cid=329</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://www.unfish.net/rss.php?version=2.0&amp;type=comments&amp;cid=329</wfw:commentRss>
    

    <author>nospam@example.com (非鱼)</author>
    <content:encoded>
    &lt;p&gt;Django马上就要发布1.0正式版了，等了好几年，现在才准备要出来。（看官方网站上应该就是这两天了）。在接近正式版的Beta2上，官方的介绍里重点强调了一个模块，comments，于是去读了一下它的文档，果然是个好东西啊。&lt;/p&gt;&lt;p&gt;简言之，comments是一个用于给任何对象添加用户回复功能的模块。你只要在配置文件里加上这个app，在html模板里加上一个load的调用，马上就可以给你原来的对象添加回复功能。所有的回复都存储在它自己的表里。取回复数，显示回复列表，显示回复文本框都有现成的方法可以调用，而发表回复的过程则是全自动处理的。&lt;/p&gt;&lt;p&gt;看完文档的第一感觉是这个模块设计的非常巧妙，你原来的所有的model，比如文章，用户，相片，或者理财易里面的账本，收支，预算等等，全部都可以很方便的增加用户评论的功能。（当然，对于喜欢挑刺的我来说，还有一个第一感觉，它的效率可能会差一点，因为在不修改原对象的情况下，它没有办法把每个对象的评论数放到原对象的表里，而只能在显示每条对象的时候去它自己的表里取一次数据。这样如果在显示某个List的时候想显示评论数，就会造成大量的数据库读取。）&lt;/p&gt;&lt;p&gt;但是，瑕不掩瑜，这个模块的设计理念是一流的，如果海内有这样的设计，就不会需要花那么久的时间才能给迷你博客加上评论功能了。（如果把它设计的不那么灵活，通过它来维护对象所在表中的回复数也是很容易的事。）&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Tue, 02 Sep 2008 13:31:10 +0800</pubDate>
    <guid isPermaLink="false">http://www.unfish.net/archives/329-20080902.html</guid>
    
</item>
<item>
    <title>Django的自定义filter陷阱</title>
    <link>http://www.unfish.net/archives/275-20080123.html</link>
            <category>Django</category>
    
    <comments>http://www.unfish.net/archives/275-20080123.html#comments</comments>
    <wfw:comment>http://www.unfish.net/wfwcomment.php?cid=275</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.unfish.net/rss.php?version=2.0&amp;type=comments&amp;cid=275</wfw:commentRss>
    

    <author>nospam@example.com (非鱼)</author>
    <content:encoded>
    
&lt;p&gt;Django的filter提供在HTML模板中格式化内容的功能，比如用来格式化大段的文本，或者格式化时间和数字的显示，对我来说，主要是用在循环里面对数据做处理，尤其是取出来的不是model的时候。（如果是model，就可以在model里定义实例方法直接在模板里面调用了）。&lt;/p&gt;&lt;p&gt;但是直到今天，才发现了Django的自定义filter的处理方式的一个重要Bug。&lt;/p&gt;&lt;p&gt;实现自定义filter的方法，是在某个app（任意一个）目录下增加一个templatetags，并在它下面增加__init__.py把它变成一个包。然后在该目录下增加任意的py文件，在里面写自己的处理函数就可以了，然后把函数注册成filter，就可以在任意的html模板里面使用了。&lt;/p&gt;&lt;p&gt;本来这种用法已经用了很久，一直没什么问题，而且在多个项目里面都是这样用的。这多个项目运行在同一台机器上，使用lighttpd+fastcgi方式来运行。&lt;/p&gt;&lt;p&gt;今天在给一个tags文件里添加了两个函数以后，在本地测试都没有问题了，结果传到服务器上打开那个页面，却提示新加的那个filter不存在，invalid filter。找来找去找不到问题，后来只想到一个结果：多个不同的项目里面同名的自定义filter文件会冲突。配置文件里面找了几圈也没找到限定加载templatetags的路径的地方。但是使用fastcgi方式的话，每个项目使用自己的manage.py runfcgi方式来运行，各自使用独立的内存空间，怎么会跑去加载别人的filter文件呢？&lt;/p&gt;&lt;p&gt;后来在limodo的网站上看到了一句话，说django的load filter文件的语法是没有项目限定符的，同名的文件只会加载一个，所以他加了个patch，允许在load的时候加上项目限定名。不过这样处理有点麻烦了，我还是用个简单的方法吧。把topic_function.py改成licaie_topic_function.py，所有该项目里面用到的地方都改掉，上传到服务器测试，OK了。&lt;/p&gt;&lt;p&gt;我至今也没有相通，在fastcgi模式下，而且它们并不知道别的项目的物理位置，怎么会出现这样的一个冲突呢？目前还是因为新函数报错，比较容易看到错误，而如果是同名函数但是功能不同，那就更麻烦了，也许跑上半月你都还不知道这里有个错误。&lt;/p&gt;
 
    </content:encoded>

    <pubDate>Wed, 23 Jan 2008 16:59:48 +0800</pubDate>
    <guid isPermaLink="false">http://www.unfish.net/archives/275-20080123.html</guid>
    
</item>
<item>
    <title>Django的服务器选择</title>
    <link>http://www.unfish.net/archives/239-20071127.html</link>
            <category>Django</category>
    
    <comments>http://www.unfish.net/archives/239-20071127.html#comments</comments>
    <wfw:comment>http://www.unfish.net/wfwcomment.php?cid=239</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.unfish.net/rss.php?version=2.0&amp;type=comments&amp;cid=239</wfw:commentRss>
    

    <author>nospam@example.com (非鱼)</author>
    <content:encoded>
    &lt;p&gt;在Django官方的配置文档上，建议的生产环境服务器是Apache+Mod_Python，同时也说明了Lighttpd+FastCGI是个不错的选择，有时还可以提供更好的性能。&lt;/p&gt;&lt;p&gt;对于性能问题，许多用户有着完全不同的意见，在一份比较可信的报告上，使用最精简的Apache编译，配合Mod_Python模块运行Django，跟Lighttpd+FastCGI的方案相比，在单用户并发的情况下，性能稍弱，但是在10并发和100并发的情况下，性能要高出40%左右。&lt;/p&gt;&lt;p&gt;当然，通常情况下你的Apache不可能是最精简状态，Apache的性能会随着加载模块的数量逐步降低。（当然，你可以为每一种不同的应用编译一个Apache实例，虽然比较麻烦，但是的确是个好的选择）而Lighttpd本身是轻量的，功能的多少对性能影响不大。而且随着并发量的上升，Apache的进程模式对系统资源占用很厉害，所以对于硬件资源有限的平台，Lighttpd应该是个更好的选择。&lt;/p&gt;&lt;p&gt;另外还有一个重要的要考虑的问题，你的服务器是否只运行Python？以我个人的经验，Apache在同时加载了Mod_Python和php模块的话，Python的某些函数会出现奇怪的结果。但是如果没有php模块，就不会出现这个问题。这个问题被人称为“Linux上的dll黑洞”，不同的模块如果使用到了不同版本的外部项目，那么它们就会产生影响。在CGI模式则不会，所有的模块都是完全独立的。所以如果需要同时运行Django和PHP程序，那么两者不能同时使用Apache的模块方式，至少有一个要使用CGI模式（或者分别编译到两个Apache实例上）。&lt;/p&gt;&lt;p&gt;PS：据说另一个新的小型WEB服务器Ngnix也不错，其性能和资源消耗都跟Lighttpd差不多，美国的许多空间提供商使用了这个服务器，在同样的硬件平台上，甚至可以提供Apache 10倍的负载能力，而且，它可以在不间断服务的情况下进行软件升级，Apache的Rewrite规则也可以在很少修改的情况下直接拿来使用，都是不错的选择。&lt;/p&gt; 
    </content:encoded>

    <pubDate>Tue, 27 Nov 2007 09:20:58 +0800</pubDate>
    <guid isPermaLink="false">http://www.unfish.net/archives/239-20071127.html</guid>
    
</item>
<item>
    <title>6种流行的WEB框架性能测试</title>
    <link>http://www.unfish.net/archives/238-20071126.html</link>
            <category>Django</category>
    
    <comments>http://www.unfish.net/archives/238-20071126.html#comments</comments>
    <wfw:comment>http://www.unfish.net/wfwcomment.php?cid=238</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.unfish.net/rss.php?version=2.0&amp;type=comments&amp;cid=238</wfw:commentRss>
    

    <author>nospam@example.com (非鱼)</author>
    <content:encoded>
    &lt;p&gt;原文地址：&lt;a onclick=&quot;javascript:urchinTracker(&#039;/extlink/www.alrond.com/en/2007/jan/25/performance-test-of-6-leading-frameworks/&#039;);&quot; href=&quot;http://www.alrond.com/en/2007/jan/25/performance-test-of-6-leading-frameworks/&quot;&gt;http://www.alrond.com/en/2007/jan/25/performance-test-of-6-leading-frameworks/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;原文对六种流行的WEB开发框架进行了简单的性能测试，分别是：&lt;br /&gt;CodeIgniter on PHP &lt;br /&gt;Catalyst on Perl &lt;br /&gt;Django on Python &lt;br /&gt;Django on Python with Psyco &lt;br /&gt;RubyOnRails on Ruby &lt;br /&gt;Symfony on PHP &lt;br /&gt;TurboGears on Python &lt;/p&gt;&lt;p&gt;比较的标准首先是大流量下的稳定性，其次是性能。测试的方法很简单，页面只输出一个Hello world字符串，不涉及任何数据库操作，否则整个网站的性能就会因为数据库的影响而趋向于集中。&lt;/p&gt;&lt;p&gt;测试用的硬件和系统：&lt;br /&gt;CPU: AMD OpteronT Processor 146 (2 GHz)&lt;br /&gt;Memory: 2 GB&lt;br /&gt;OS: Debian 3.1 (Linux 2.6.14)&lt;br /&gt;Web-Server: nginx/0.5.5&lt;/p&gt;&lt;p&gt;测试软件：&lt;br /&gt;Siege 2.65 &lt;a onclick=&quot;javascript:urchinTracker(&#039;/extlink/www.joedog.org/JoeDog/Siege&#039;);&quot; href=&quot;http://www.joedog.org/JoeDog/Siege&quot;&gt;http://www.joedog.org/JoeDog/Siege&lt;/a&gt;&lt;br /&gt;Http_load 12.03.2006 &lt;a onclick=&quot;javascript:urchinTracker(&#039;/extlink/www.acme.com/software/http_load/&#039;);&quot; href=&quot;http://www.acme.com/software/http_load/&quot;&gt;http://www.acme.com/software/http_load/&lt;/a&gt;&lt;br /&gt;ab 2.0.41-dev Rev: 1.141&lt;/p&gt;&lt;p&gt;这套硬件和软件系统应该说还是相当有代表性的，所以其结果很值得参考。具体的测试参数和测试细节还有结果的详细数字和图标可以到原文链接去看，这里只讲一下最终的结果。&lt;/p&gt;&lt;p&gt;第一名：Django 占用CPU最少，性能超过第二名好几倍，使用threaded模式比prefork模式要快15%左右，（在&lt;a onclick=&quot;javascript:urchinTracker(&#039;/extlink/blog.opensource.org.cn/hdcola/2007/10/django-1.html&#039;);&quot; href=&quot;http://blog.opensource.org.cn/hdcola/2007/10/django-1.html&quot; target=&quot;_blank&quot;&gt;一个中国的作者的测试&lt;/a&gt;情况下，threaded模式比prefork模式快近十倍），但是在高负载的情况下，threaded模式会死掉，而且无法自动重启，必须手工重启WEB服务器，这对于生产环境服务器是不可接受的。另外，使用Psyco来加速的话，两种方式下速度都可以提高20%左右，但是内存占用量会增加1-3倍，如果硬件资源没问题，就可以考虑这种方式。&lt;/p&gt;&lt;p&gt;第二名和第三名分别是TurboGears和RoR 1.1.6，它们速度差不多，但是不同负载量下的表现不同。&lt;br /&gt;RoR 1.2.1的速度比1.1.6要慢2-4倍，而且在高负载下CPU占用也大一倍。&lt;/p&gt;&lt;p&gt;PHP的框架速度是最慢的，比Django慢了35倍。但是在加载了eAccelerator加速器以后速度有大幅提升，只比Django慢两倍了。&lt;/p&gt;&lt;p&gt;作者后来又做了一次额外测试，增加了几个新兴的框架，但是最终结果并没有变，还是证明Django是最佳选择。而且，Python非常容易上手。另外，同样基于Python的框架Pylons也不错。&lt;/p&gt; 
    </content:encoded>

    <pubDate>Mon, 26 Nov 2007 20:52:01 +0800</pubDate>
    <guid isPermaLink="false">http://www.unfish.net/archives/238-20071126.html</guid>
    
</item>
<item>
    <title>Django: 初始化数据及安装时代码</title>
    <link>http://www.unfish.net/archives/232-20071122.html</link>
            <category>Django</category>
    
    <comments>http://www.unfish.net/archives/232-20071122.html#comments</comments>
    <wfw:comment>http://www.unfish.net/wfwcomment.php?cid=232</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://www.unfish.net/rss.php?version=2.0&amp;type=comments&amp;cid=232</wfw:commentRss>
    

    <author>nospam@example.com (非鱼)</author>
    <content:encoded>
    &lt;p&gt;原文地址：&lt;a onclick=&quot;javascript:urchinTracker(&#039;/extlink/www.b-list.org/weblog/2007/nov/21/install-time/&#039;);&quot; href=&quot;http://www.b-list.org/weblog/2007/nov/21/install-time/&quot;&gt;http://www.b-list.org/weblog/2007/nov/21/install-time/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;PS：&lt;a onclick=&quot;javascript:urchinTracker(&#039;/extlink/www.b-list.org/weblog/&#039;);&quot; href=&quot;http://www.b-list.org/weblog/&quot;&gt;The B-List&lt;/a&gt;是个很牛的Django博客，大量的技巧和教程，英语好的一定要去订阅，怕看英语的，就等我的翻译吧。&lt;/p&gt;&lt;p&gt;经常被问到的一个问题是：我怎么样为我的app提供初始化数据？或者一个相似的问题：我怎么样保证我的程序在通过syncdb安装的同时运行某些代码。Django提供了多种途径实现这个功能，你可以根据具体的需求选择不同的实现方式。虽然这些功能在文档里都已经说明了，但是还是会遇到很多问题，所以我们今天仔细看看各种不同的方式之间的区别，了解哪一种更适合你。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;提供SQL语句初始化数据&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;这是最古老的方式（从Django一开始就有这个功能）也是最简单的方式（不管是你需要做的部分，还是它所支持的功能）来为你的Application提供一些初始化数据：你只需要提供一个SQL文件，包含标准的Insert语句，Django会在创建了数据表以后执行你的SQL文件。&lt;/p&gt;&lt;p&gt;要使用该方式，你需要在你的app目录下增加一个&amp;quot;sql&amp;quot;目录，对应你的每个model所需要的初始化数据，提供一个&amp;quot;model名.sql&amp;quot;的文件，model名是跟你定义的model相同的名字（这里使用小写，也就是get_model()方法返回的名字或者在model的meta信息中定义的model名字）。比如，我有一个名为blog的application，其中包含一个Entry的model，那我就可以在blog里面的sql目录下放一个entry.sql文件，里面写insert语句就可以了。&lt;/p&gt;&lt;p&gt;在这个文件里你也可以放其它的SQL语句，不仅仅是INSERT，但是需要提醒你，同一个app的多个SQL初始化文件，其执行顺序是不一定的，而且也不是所有的SQL语法都支持。为了处理不同的数据库类型的SQL兼容性，Django会对该文件进行处理，而不是直接去执行它。&lt;/p&gt;&lt;p&gt;你可以使用manage.py的sqlcustom命令查看一个app是否提供了初始化SQL。&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://www.unfish.net/archives/232-20071122.html#extended&quot;&gt;继续阅读 &quot;Django: 初始化数据及安装时代码&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Thu, 22 Nov 2007 15:29:13 +0800</pubDate>
    <guid isPermaLink="false">http://www.unfish.net/archives/232-20071122.html</guid>
    
</item>
<item>
    <title>为什么我从Ruby on Rails转向Django又转回来</title>
    <link>http://www.unfish.net/archives/222-20071109.html</link>
            <category>Django</category>
    
    <comments>http://www.unfish.net/archives/222-20071109.html#comments</comments>
    <wfw:comment>http://www.unfish.net/wfwcomment.php?cid=222</wfw:comment>

    <slash:comments>6</slash:comments>
    <wfw:commentRss>http://www.unfish.net/rss.php?version=2.0&amp;type=comments&amp;cid=222</wfw:commentRss>
    

    <author>nospam@example.com (非鱼)</author>
    <content:encoded>
    &lt;p&gt;趁有时间，再翻译一篇文章，原文地址：&lt;a onclick=&quot;javascript:urchinTracker(&#039;/extlink/blog.carlmercier.com/2007/01/30/why-i-moved-from-ruby-on-rails-to-pythondjango-and-back/&#039;);&quot; href=&quot;http://blog.carlmercier.com/2007/01/30/why-i-moved-from-ruby-on-rails-to-pythondjango-and-back/&quot;&gt;http://blog.carlmercier.com/2007/01/30/why-i-moved-from-ruby-on-rails-to-pythondjango-and-back/&lt;/a&gt;&lt;/p&gt;&lt;p&gt;在2006年3月份的时候，我决定完全重写Ajaxwhois.com网站。我已经学了很长时间的Ruby on Rails，知道它就是最合适的平台。Ruby on Rails可能对刚刚从Java或.Net转过来的程序员有点难用，但是只要很短的时间，你就会适应它。&lt;/p&gt;&lt;p&gt;透明的代码生成，糟糕的IDE工具，还有更坏的，没有好用的调试器，这些导致我转向Ruby遇到了一些困难，我已经习惯了Visual Studio .net，习惯了它的智能感知。我好怀念它啊。&lt;/p&gt;&lt;p&gt;每一个使用Rails的新手都会很快的明白它为什么会这么流行。首先，既便我还不是一个太熟练的Rails程序员，我现在使用ROR的开发效率仍然能够达到asp.net和C#两倍以上。这要多亏了MVC（Model, View, Controller），DRY（Don&#039;t Repeat Yourself）和约定高于配置的理念。所有的数据库处理代码都已经自动生成（甚至不需要运行任何代码生成工具），还有自带的模板系统和Ajax支持。&lt;/p&gt;&lt;p&gt;用ROR的日子是美好的，用的越久我就越喜欢它，直到2006年的8月初。我已经准备好了Ajaxwhois网站的2.0版本，准备上线了。认识了很多Rails专家，我以为把我的程序发布到生产环境服务器是件很简单的事，但是，我错了。虽然安装Linux（Ubuntu Daper Drake 64位）、Lighttpd、Mysql和Mongrel都很正常，但是我遇到了很奇怪的问题，主要是Mongrel的问题。有时候，Mongrel进程就那样死掉了，进程列表中看不到，也没有任何明确的原因，这时候服务器还没有任何流量，因为我还没把DNS转过来。还有的时候，Mongrel疯狂的占用CPU到99%，我不得不手动Kill掉它再重启。&lt;/p&gt;&lt;p&gt;经过一番搜索和无数次的重装，我发现Mongrel跟64位Ubuntu不太兼容。Mongrel打过这个补丁，但是并没有解决我的问题，它还是会每天死很多次，而且我找不出哪里出的问题。问了几个Rails专家级的朋友，他们也都没有办法，我受不了了。&lt;/p&gt;&lt;p&gt;我不能再浪费更多的时间了，于是我拿了本Python的书，并且又一次重写了整个网站，在Python里我使用了Django框架。我从来没有Python和Django的编程经验，但是转换是相当容易的，因为Ruby和Python的语法很多地方很想像。&lt;/p&gt;&lt;p&gt;Python和Django给我的体验非常棒，每个开发人员都应该考虑一下。不过，我很快就怀念ROR了。Ruby支持真正的private/public/protected方法（Python只是用它的命名方式模拟一下），而且它的语法更宽松（Python里面每个方法都要写()，烦死我了）。Django不像Rails那么简单，需要更多的代码完成相同的工作。Django还有些小问题让人觉得很不爽，比如需要手工传递参数到view，数据库处理也不像Rails的ActiveRecord完成的那么漂亮。这种问题还有很多。&lt;/p&gt;&lt;p&gt;另一方面，Python比Ruby要快，而且内存占用更少。而且我真的爱上了Python的缩进语法。更重要的，Python和Django工作正常。我从来没有遇到过像Rails那样当机的问题。&lt;/p&gt;&lt;p&gt;那么，为什么我在下个项目的时候又回到了Rails上呢？三个字：FUN。我觉得ROR用的更爽，社区庞大活跃而且很有用。可用的Rails插件很多而且核心代码的改进相当快。Rails需要的代码量更少，没有self.__awkward_method_calls()这种东西，有内建的Ajax和REST支持，更复杂的数据库操作和模板引擎。&lt;/p&gt;&lt;p&gt;那死机的问题怎么办呢？还有速度的问题呢？嗯，死机的问题消失了。别问我怎么弄的，我也不知道，它就那样消失了，我发誓！某个时间某个问题的修复解决了我的问题。但是速度的问题仍然是Rails的一个软肋。使用缓存和优化代码可以解决很多情况下的问题，而且Ruby的作者Matz正在努力的写成一个新的虚拟机，以便让Ruby至少像Python那样快。&lt;/p&gt;&lt;p&gt;我的建议是：两个都试用足够长的时间，才能发现哪一个更适合你。如果你已经有Python的编程经验，Django当然是最好的，但是如果你有Java/Perl/Smalltalk背景，ROR可能更合适。&lt;/p&gt;&lt;p&gt;PS：我的Rails问题也不能全怪Mongrel，因为我也不知道具体是哪里的问题。Mongrel是个优秀的软件，我真心的推荐它。只是如果你使用64位Ubuntu的话，盯紧一点！&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 09 Nov 2007 16:58:14 +0800</pubDate>
    <guid isPermaLink="false">http://www.unfish.net/archives/222-20071109.html</guid>
    
</item>
<item>
    <title>升级Django到svn trunk需要做的工作</title>
    <link>http://www.unfish.net/archives/213-20071102.html</link>
            <category>Django</category>
    
    <comments>http://www.unfish.net/archives/213-20071102.html#comments</comments>
    <wfw:comment>http://www.unfish.net/wfwcomment.php?cid=213</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.unfish.net/rss.php?version=2.0&amp;type=comments&amp;cid=213</wfw:commentRss>
    

    <author>nospam@example.com (非鱼)</author>
    <content:encoded>
    &lt;p&gt;花了不少时间，走了不少弯路，多了不少Bug，总算是把理财易的Django升级到svn trunk版本了，值不值得还不知道，不过，用新的总归没什么坏处，而且，1.0已经不远了，现在做好准备也不错。&lt;/p&gt;&lt;p&gt;首先删除原来的Django 0.96版的安装，全新安装svn trunk版，启动服务器，打开首页，出现一堆错误。首先是前面提到过的那个用来做“记住密码”密码功能的自定义的&lt;a href=&quot;http://www.unfish.net/archives/210-20071029.html&quot; target=&quot;_blank&quot;&gt;DualSessionMiddleware&lt;/a&gt;，它引用的页面发生了变化，SessionWrapper类已经不存在了，所以启动报错。暂时修改Settings文件，使用默认的session middleware，OK，通过了。然后提示_()函数不存在。这个是gettext函数，用来做多语言界面的，查了一下 兼容列表，果然，这个函数被移除了。于是在所有出现这个函数的文件里加上from django.utils.translation import ugettext as _，通过。进留言板，进不去，提示编码转换错误，什么&amp;quot;ascii can not decode”什么的，跑到官网一查，说是什么修改了对Unicode字符串的处理，现在整个系统各个环节的Unicode已经统一（大概是输入，转换，和输出）。结果是：需要把所有的用%来拼接字符串的地方，加上u标志。比如s=&#039;用户名%s不存在&#039; % username，如果这个username是中文，这里就会报错，一定要把前面的这个变量加上u，标明这是Unicode变量。&lt;/p&gt;&lt;p&gt;改了N多地方，总算又通过了，然后继续测试，发现另一个地方又是转换错误，但是这里只是把一个包含中文的数组用join的方法串起来，我去哪里加这个u呢？想来想去，找到了定义这些中文的地方，在每一个中文变量的前面加上u，通过了。现在，代码变得相当丑陋了。（为了给省和市的名字加这个u，做了近200个替换，也不知道有没有留下后遗症）。&lt;/p&gt;&lt;p&gt;想到的地方都解决了，就更新到了服务器上。结果第二天有人报告无法注册，原来检查用户名是否符合规则的地方也变了。以前获取到的用户输入都是UTF8的，用正则来判断是否包含中文，需要先转换成Unicode，于是对输入字符串做了一个decode(&#039;utf8&#039;)，现在，这一步变成了多余的，所有的输入本来就是Unicode的。（但是读写数据库的时候似乎会自动转换成UTF8，否则写入Mysql应该会报错。）&lt;/p&gt;&lt;p&gt;后来又想到WAP那边也有中文的处理，打开手机一试，果然如此，中文用户无法登录了。&lt;a href=&quot;http://www.unfish.net/archives/16-20070430.html&quot; target=&quot;_blank&quot;&gt;以前的解决方案&lt;/a&gt;是利用客户端的能力，把输入的字符串编码成URL模式，中文会变成%D7%B7这样的字符串，拿到以后用urllib.unquote来解析出来，然后，如果客户端是UTF8的，要用decode(&#039;utf8&#039;)来处理，如果客户端是gb2312的，要用decode(&#039;gb2312&#039;)来处理。（虽然我在所有的WAP页面里都指定了编码是UTF8，但是在我的Palm上使用Blazer浏览器，仍然是GB2312编码的。）因为无法预知客户端如何编码，所以用try做两次解码。但是现在，不管用哪个，都会报错。&lt;/p&gt;&lt;p&gt;在这个问题花了许多时间，尝试各种各样的解码规则，都失败了。后来终于想到了问题所在，在不使用任何解码的情况下，服务器端接收到的是%D7%B7的字符串，说明这一步是正确的，然后，在unquote以后，文字就已经变成乱码了，按理说，应该只是把%变成\x而已。这一步实在是出乎意料，因为按理说收到的都是英文字符串，难道对英文字符串的处理也会因为编码而不同？经过测试，还真是如此。以前request.get拿到的字符串是没有编码的，也就是说%D7%B7就是作为一个普通的ascii字符串，但是现在，这个字符串被作为了Unicode字符串。unquote方法在解析Unicode字符串的时候，得到的结果是错误的。知道了问题，答案就找到了。先对输入的字符串做一个encode(&#039;ascii&#039;)，再进行unquote，啊，终于结束了。&lt;/p&gt;&lt;p&gt;另外，系统在从0.96更新到0.96.1的时候（也就是打了那个多语言方面的补丁以后），多语言功能消失了。IE的用户看上去是正常的，但是Firefox的用户看到的都是英文。（如果Firefox的语言选项里只有zh和zh-cn，那他看到的是中文，如果有了en，哪怕是在最下面，还是会显示英文界面。）跑到google group里去发了个帖子，最后得到了官方的回复，这是他们的一个Bug，在修改的过程中出错了，而且，只有zh-cn，zh-tw和pt-br出错，zh-cn需要改成zh_CN，在conf下面的default setting文件里。算了，还是不要改了，反正暂时关了多语言也没关系，等官方版本修改了这个再说吧。&lt;/p&gt;&lt;p&gt;11月4号更新：今天根据用户的反馈，测试了一下，发现Opera访问WAP的问题还是没有解决，中文编码不正确。不只是WAP上，用PC上的Opera登录WAP站，它的中文也有问题。在Postfield里面使用:e标识符以后，其它的浏览器都会根据自己的编码(gb2312或utf8)对中文进行URL编码然后发送，但是在Opera上编码以后，却丢了一半的值（一个汉字经过GB2312的URL编码以后应该是%D7%C7这样的两组值，但是Opera却只返回了后面的这一个，解码当然就不对了。&lt;/p&gt;&lt;p&gt;改了几种编码都不对，后来把:e的编码方式去掉一试，居然成功了。看来Opera对中文的兼容性已经远远超越了其它的手机浏览器，能够不编码发送完整的中文到服务器端。但是把:e去掉以后，别的浏览器又不对了（Palm上的Blazer会丢掉最后一个汉字）。不过既然知道了具体的现象，也就有解决办法了。通过服务器端判断User_Agent是否包含Opera字符来判断用户使用的是不是Opera浏览器，如果是，在生成页面的时候就不要添加:e标识符。经过测试，PC上和Palm上的Opera Mini都已经可以正常使用中文了。&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 02 Nov 2007 14:59:11 +0800</pubDate>
    <guid isPermaLink="false">http://www.unfish.net/archives/213-20071102.html</guid>
    
</item>
<item>
    <title>Django:更简单的实现记住密码功能</title>
    <link>http://www.unfish.net/archives/210-20071029.html</link>
            <category>Django</category>
    
    <comments>http://www.unfish.net/archives/210-20071029.html#comments</comments>
    <wfw:comment>http://www.unfish.net/wfwcomment.php?cid=210</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.unfish.net/rss.php?version=2.0&amp;type=comments&amp;cid=210</wfw:commentRss>
    

    <author>nospam@example.com (非鱼)</author>
    <content:encoded>
    &lt;p&gt;Django的设计里，Session的保存是借助Cookie的，Cookie的保存默认有两种周期，浏览器生命周期和14天周期。这两者的选择在settings.py里面的一个参数，设成True就是前者，设成False就是后者。但是，我们通常的需求是用户登录的时候可以选择是否记住登录，如果不选就是前者，如果选中，就使用后者，但是Django却没有留下这个接口。&lt;/p&gt;&lt;p&gt;在我以前的文章里面，是通过直接修改Django的源代码，改了它的sessionMiddleware来解决的，今天在浏览它的google group的时候，终于找到了一个比较正规的方法。其实其原理跟我那个方法是完全一样的，修改sessionMiddleware，让它在设置Cookie之前从当前的session里面读取一个值，看看是否要记住密码，从而控制生成哪一个周期的Cookie。&lt;/p&gt;&lt;p&gt;但是他的做法就比我要高明了，我的做法直接修改了Django的源代码，所以导致每次升级的时候会很麻烦，因为会覆盖以前的修改。但是他的做法是自己重新写了一个sessionMiddleware，基本上，这个文件应该就是直接把原来的拷了出来，然后做修改。只要在settings文件中指定这个middleware的类，让你的项目使用自己的这个就可以了。这样，系统自己的就完全被忽略掉了。&lt;/p&gt;&lt;p&gt;这个博客不能贴代码，需要看源代码的去我的博客堂地址吧：&lt;a onclick=&quot;javascript:urchinTracker(&#039;/extlink/unfish.cnblogs.com/&#039;);&quot; href=&quot;http://unfish.cnblogs.com/&quot;&gt;http://unfish.cnblogs.com&lt;/a&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Mon, 29 Oct 2007 16:00:29 +0800</pubDate>
    <guid isPermaLink="false">http://www.unfish.net/archives/210-20071029.html</guid>
    
</item>
<item>
    <title>Python Django WAP中文乱码</title>
    <link>http://www.unfish.net/archives/16-20070430.html</link>
            <category>Django</category>
    
    <comments>http://www.unfish.net/archives/16-20070430.html#comments</comments>
    <wfw:comment>http://www.unfish.net/wfwcomment.php?cid=16</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.unfish.net/rss.php?version=2.0&amp;type=comments&amp;cid=16</wfw:commentRss>
    

    <author>nospam@example.com (非鱼)</author>
    <content:encoded>
    &lt;p&gt;虽然不太想在这里写技术性的文章，不过为了凑数，同时增加点关键字，还是写点吧。&lt;/p&gt;&lt;p&gt;&lt;a onclick=&quot;javascript:urchinTracker(&#039;/extlink/www.licaie.com/&#039;);&quot; href=&quot;http://www.licaie.com/&quot; target=&quot;_blank&quot;&gt;理财易&lt;/a&gt;在运营的过程中，会员提出是否可以开发WAP记账的功能。虽然别的记账网站都已经有了这个功能，但是我一直对这个不太感冒，因为我自己都没有用过WAP功能。所以，我觉得别人也不太可能用这种东西。不过既然有人提出来了，就研究一下吧。&lt;/p&gt;&lt;p&gt;开发过程还是比较顺利的，Django的模板系统可以套用在任何框架上，所以只用了一个晚上，一个简易的WAP版记账系统就出炉了。登录／记账／查看最新记账，都有了。结果，很快发现一个比较严重的问题，发送数据不支持中文。&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://www.unfish.net/archives/16-20070430.html#extended&quot;&gt;继续阅读 &quot;Python Django WAP中文乱码&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Mon, 30 Apr 2007 12:30:00 +0800</pubDate>
    <guid isPermaLink="false">http://www.unfish.net/archives/16-20070430.html</guid>
    
</item>

</channel>
</rss>