首页  »  编程

Django也会智能Lazyload?

今天在本地很快实现了最新评论的功能。在右手边的最新评论点击连接时会去到文章的页面,并定位到评论所在的锚点上,也就是说,我需要在页面上取得评论所在文章的ID,也就是需要这样:{{comment.comment_to.id}}。这时候,我仅仅需要获得文章的ID,但不知道Django是否会到数据库去把相应的文章查出来(我没有使用Select_relate)之后再拿ID呢?不过Django好现没有可以设置打印执行Sql语句的开关,并不能通过配置来看到运行时Django查了多少次数据库。而这样的功能,我使用Java的Hibernate时就有的。

我Google了一下,发现Django本身是没有提供日志和Sql打印功能的。而有人做了些工作,如这位仁兄写了个中间件,可以在页面上打印出该次请求一共执行了多少条语句,每条语句的执行时间。而这里有个叫Django-logging的项目,为Django提供Logging,包括Sql的打印。等会就试验一下。Django天生就是Lazyload的,需要用到数据的时候才去加载,我希望,我的担心是多余的。一会尝试使用Log来看看测试结果吧。

结果一:Select_related对允许为空的外键不起作用。
我的查询语句是这样:entries = blog.entry_set.filter(status=1).select_related(depth=1).order_by('-id') 查询一个Blog下面所有的Entry,并把有关联的数据一并抓取出来(根据ForeignKey)。也就是说,在查询Entry的同时查出Blog,作者,分类等信息。
但是情况是,我在页面找印这些文章的时候,需要把文章的分类也打显示出来,这时候,Django却跑到数据库执行了N次查询分类的语句。暴汗。这是经典的Hibernate的延迟加载用得不恰当的情况啊!我一看打印出来的查询语句,有查相关的作者、Blog,但偏偏没有查分类。最后我回到Model里比较了一下,我的分类属性上面设置了null=true,原意是让文章可以没有分类。最后我尝试着去掉Null=true,一运行。那N条查询不见了。靠。。原来Select_related在外键允许空的情况下是行不通D。

结果二:Django不会智能LazyLoad。要手动去Select_related。
回到对Django有疑问的情景,recent_comments = Comment.objects.filter(blog=blog).order_by('-comment_time')[:10] 查出本BLog最新的十条评论。我的假设是,Comment本身保存有Entry的ID,所以在仅仅是获取Entry的ID的时候不需要去数据据里找,Hibernate的LazyLoad就是这样做的,使用动态代理的解决方案。我想在Python这样的动态语言的解决方案更佳,但事实证明我错了。上面的语句又产生了经典的1+N的问题。我在页面根据评论取EntryID的时候{{comment.entry.id}}还是去加载了一次数据,搞笑的是,这句查询需要得到的数据对我有用的是ID,但是查询条件就是ID。我只好把查询语句改成:
recent_comments = Comment.objects.select_related(depth=1).filter(blog=blog).order_by('-comment_time')[:10]。显示去Select_related。宁愿直接去Join相关的表,也不要做1+ N的查询。显然这很浪费,仅仅为了一个ID,要Join好几个表。

WYMeditor

WYMeditor。又一个RichText editor,我怎么说又呢?猛地看上去我以为又一个HtmlArea或者FCKeditor或者Tinymce。看到Demo和features才知道,这东西蛮有个性的。打算在本站使用一下的。Features:

  • 完全兼容XHTML strict + CSS
  • 没有Font,你不能对字体颜色、大小,字体对进调整,WYMeditor是基于CSS的
  • 被设计用来易于与你的应用相结合
  • 不需安装,100%的Javascript代码,无插件,无扩展
  • 很简单的Javascript代码,很易懂
  • 继续保持简单
  • 我们致力于测试友好的代码,保证新功能的稳定性及有效性
  • 图像、连接、表格支持
  • 通过CSS支持皮肤
  • 免费并且开源,完全适合你的需要

N小时后。

测评结果:

一、很固执,wymeditor.js一定要位于一个名叫wymeditor的文件夹下面,不然一律罢工,报错XmlHelper找不到,这个问题很怪异也很变态,花了我好多时间才找到原因。

二、提交时不更新TextArea的内容,要手动写程序或者在Submit的Button指定Class为wymupdate,我试过第二种方法,由于我的Button还需要使用Onclick方法,没戏。这样很变态。

三、指定CSS的时候,要按规则对CSS进行注释,偶笨,不得法,注释的CSS搞得整个Editor出错不能用。

总的来说,指导思想很好(What You See Is What You Mean),只是目前处于Beta阶段。我还是先使用最熟悉的FCK吧。等待Wymeditor的成熟!

放弃Mod_fastcgi+apache?

尝试了一晚上,Apache没有重启成功。Mod_fastcgi在2003年的时候就已停止了开发。那时只是支持到Apache2.0.X版,现在使用的都2.2.X了,官方虽然提供了一个Patch,但我本地没有C编译环境,于是不了了之。此外,Fastcgi本身有些问题,线程出问题的时候可能关闭不了,不过中国(没有错吧?)有人解决了这个问题,那是另一个项目“fcgid”。用这个可以直接代替Fcgi。

寻找另一种部署FastCGI的方式。。lighttpd?

Django + mod_python

Django + mod_python的部署方式的基础是我的上一篇文章。前提python、Django、Apache、Mod_python安装完备。

部署方式有两种:一是加直接在apache的httpd.conf下面加一个一个Location的元素:

<Location "/mysite/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE myblog.settings
PythonDebug On
PythonPath "[r'F:\\develope\\projects\\myblog'] + sys.path"
</Location>

主要留意两个参数:SetEnv DJANGO_SETTINGS_MODULE 指定你的Django应用的settings.py。PythonPath Python程序的路径,如果你的Django应用不在Sys.path里面,那么加上你的应用路径,注意,如果你的项目路径为:D:\\projects\myblog那么,Python Path应该填D:\\projects。

这样,你可以通过http://localhost/mysite来访问你的应用,不过有一个问题,Django会把“mysite”当作请求的URL的一部分。你必须要把URLConf里的配置全加上mysite。显然,这种做法并不是很理想的。

为解决上面的URL问题,可以通过VirtualHost来配置使用另一个虚拟机作为Django应用的所在地。所不同的是,还是可以从根目录下访问应用,不过使用了不同的端口:

Listen 127.0.0.1:81
<VirtualHost 127.0.0.1:81>
<Location "/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE myblog.settings
PythonPath "[r'F:\\develope\\projects\\myblog'] + sys.path"
PythonDebug On
</Location>
</VirtualHost>

这一次,可以通过http://localhost:81/来访问应用了。

下面的文章讲述如何处理静态文件与FastCGI + Django

安装Mod_python

编程 jeff  |  2007-09-16 1 pythonapache

Mod_python的使用要求与Apache结合。我使用的Apache版本为2.2,python为2.5,配套的Mod_python为3.3.1。安装及调通的步骤如下:

一、安装Apache。到http://httpd.apache.org/下载最新版本的Apache,如果是Windows环境,直接下载可执行文件安装完就可以了。测试Apache是否正常工作,直接访问http://localhost就可以,当看到It works表示安装成功了。

二、安装Python。下载Python2.5版,直接安装即可。

三、安装Mod_python。到http://www.modpython.org/下载合适版本的Mod_python,注意Apache与Python的版本。在Windows下直接执行安装完之后,找到 C:/Program Files/Apache Software Foundation/Apache2.2\conf\httpd.conf(看apache安装的地方而定) 文件进行编辑,找到LoadModule部分并加上这句:LoadModule python_module modules/mod_python.so,这时候,安装Mod_python已经完成了。下面来进行测试Mod_python的工作情况。

四、测试。在本地建立一个独立的测试目录,如 D:/site,然后修改httpd.conf加入下面代码:

Alias /py d:/site/

<Directory d:/site/>

Order deny,allow

Allow from all

AddHandler mod_python .py

PythonHandler mptest

PythonDebug On

</Directory/>

上面的代表是这样的意思:定义一个别名,当访问localhost/py时,实际上是去d:/site/找文件。Directory里面定义了一些规则,注意前两行很有必要,否则有可能出现拒绝访问的情况,AddHandler mod_python .py意指针对.py文件指定一个Handler。PythonHandler mptest意指Python的Handler是mptest.py。我们在d:/site/下面添加一个mptest.py文件:

from mod_python import apache

def handler(req):

req.content_type = 'text/plain'

req.write('hello world')

return apache.OK

重启Apache,访问http://localhost/py/xyz.py 得到的结果是hello world。只要是.py结束的请求都会调用mptest.py来处理。

That's all。

使用Django生成RSS

编程 jeff  |  2007-09-13 2 pythondjangorss

感谢Django强大的syndication feed framework,我可以很轻松地实现RSS的生成工作。Fallever的RSS可以从每个Blog的右下角找到。Django的官方文档见这里。文档中的第一个Example并不适合我,Fallever现在的情况是提供每个Blogger一个RSS文件,因此需要传参数,情况比较类似“A complex example”那一段。

使用Django的SFF来生成RSS太简单了。有下面几个步骤:

一、配置URLConf:

(r'^feeds/(?P.*)/rss.xml$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds})

URL表达式中,url参数实际上允许很多个“/”存在。在Fallever中的用法是:/feeds/blog/{{shortcut}}/rss.xml.那么Django会把“feeds/”后面那一大截当作URL的参数传进去生成的机器(姑且这样叫吧),Shortcut是代表一个Blog的简称。注意,"feeds/"作为RSS路径的开头是必须的。

二、写feeds。

你已经留意到了URLConf里面的第三个参数吧。feeds是一个字典,Key是Feed的类型,Value是处理该类型的类。Fallever的第一个字典是:

feeds = {'blog':recent_blog_entry}

这个字典说“feeds/”后面凡是跟着blog字样的路径全由recent_blog_entry这个类来处理。在blog后面跟着的参数从哪里可以找回来呢,我一开始就有这样的问题,原来在这里:重写Feeds类的get_object(self, bits):bits参数就是把blog后面的参数切成了数组,如/feeds/blog/jeff/rss.xml切割后bits参数是:['jeff','rss.xml']在这里我们只需要拿我们有用的元素就可以了。rss.xml这一节东西我是用来哄IE的。

三、在recent_blog_entry类里重写Feeds的几个方法:title,link,description,items,items_link。具体的在这里不说了,还有需要为这一次的Feed加上两个简单的模板。都去参考文档看吧 :)

 

Fallever更新日志

编程 jeff  |  2007-09-12 1 pythondjangomysql

今天晚上Fallever加上两个Powered by的Logo,Mysql和Django。在考虑是不是把Python也加进来。嘿。

在今晚顺便把RSS提供出来、本次提供的RSS包括:个人博客的最近更新、个人博客分类最近更新。然后,是时候调整一个后台的结构,建立一个完整的可用的博客系统。

接下来会有很多东西要做,捞捞说过,如果我把它在BlogCN上的东西全搬过来,那他以后就在这里安家。我说你不介意我暂时界面简陋、短期内开发进度不快等等你就等着吧,到时帮你搬过来。捞说,我年年25,不急。

Meta

关于本博客...

关于黑莓手机、apple、twitter、互联网、web2.0以及生活的碎言碎语。请在twitter上 follow我,欢迎同好者talk to me bbmyth AT gmail.com。博客Hosting在 webfaction。

赞助商链接

我看我听我读

最新评论

标签

python 空间 开发 计划 年假 工作 诗歌 音乐 西片 恐怖 惊变 django mysql rss 文艺片 太阳 彩色 电影 apache 部署 factcgi lighttpd javascript editor MYMeditor sql 日志 java hibernate orm 数据库 英伦 摇滚 原创 中间件 朋友 erlang 并发 函数式编程 旅游 云南 丽江 发呆 学习 编程 技术 lucene 全文搜索 中文分词 乐队 模板 分页 成功 google pagerank 中文 更新 个性化 秋天 互联网 web ext json ajax 事业 职业 读书 开源 香港 澳门 忧郁 冬天 compass dvd 广州 地下 暴力 美学 声音玩具 独立 备份 数据 琐事 博客 生活 体验 卖唱 接口 设计模式 图表 wiki moin 遇窃 air ria 需求 设计 信息 健康 感悟 人生 真诚 life jquery 杭州 灾害 2008 中国 灾难 哀悼日 jmesa grails flex flash 捐赠 scrum 软件过程 快速开发 plone cms nuexo zope 左小诅咒 demo prototpye AMF actionscript 汉诺塔 算法 递归 结婚 感情 opensource 网络 beautifulSoup 管理 大理 香格里拉 休假 鼻炎 许巍 感性 2009 随想 cpug 聚会 出差 北京 api 创业 商城 blackberry 手机 TD 交流 处事 为人 房子 经济 手机仿真 在线服务 嵌入式 海鲜 p2p easymule apple 技巧 thing gtd task gfw vpn 穿墙 代理 软件管理 翻译 mac 英语 caffeine 休眠 搬家 主机 prism firefox mozilla 免费 php codeigniter url blogspot mindmap mindnode htmlparse easyurl 产品 黑莓 rim 试手机 豆瓣 twitter 微博 杂记 时空 亲人 dabr webfaction host 快速查看 safari appale 桌面 snow 升级 leopard finder 权限 glims python主机 合租 ruby主机 快捷键 itunes 时间管理 原型 画图 招聘 hosting 写作 软件 家庭 广州技术沙龙 postgres 云计算 fuckgfw 内容审检 谷歌 chrome linux odbc database freetds R 统计 书签 浏览器 bookmark tinymce 文件管理 分享 忙碌 旅行 马来西亚 图维导图 freemind 工具 pinax develope shell dropbox barcamp

日志分类

友情链接

博客归档

PowerBy