存档

2010年5月 的存档

WEB3D 技术

2010年5月31日 没有评论

        3D技术的魅力实在是太有诱惑力了,目前提供在线3D技术的因为带宽限制还不是很普及,不过目前市面上还是出现了部分3D技术实现产品,一些是通过3D引擎实现,还有部分是通过“伪”3D技术,比如像新浪乐居的3D看房,就是采用“鱼眼”技术进行图片拼接实现伪3D效果。

        以下是本人找到的一个3D实现效果,感觉成熟度还不错。


       在线演示地址:http://www.planedit.com/planedit_dark.php?casename=demo&level=0

  那么,什么是Wed3D?它是如何发展起来的?它的最新发展怎样?用于哪些应用?还存在哪些问题?下面我们一一道来。

  VRML——互联网3D图形的开放标准

  VRML是3D图形和多媒体技术通用交换的文件格式,它基于建模技术,描述交互式的3D对象和场景,不仅应用在互联网上,也可以用在本地客户系统中,应用范围极广。由于网上传输的是模型文件,故其传输量大大小于视频图像。VRML97使任何一个3D图形爱好者能制作可在互联网上实时渲染的3D场景模型。

  形形色色的互联网3D图形软件

  制作互联网3D图形的软件并没有完全遵循VRML97标准,许多公司推出了它们自己的制作工具,使用专用的文件格式和浏览器插件,类似的软件大约有三十几种之多。这些软件各有特色,都比VRML有了进步,在渲染速度,图像质量,造型技术,交互性以及数据的压缩与优化上有都胜过VRML之处。

  互联网3D图形的关键技术——实时渲染引擎

  实时渲染引擎的作用是解释并翻译实施场景模型文件的语法,实时渲染从服务器端传来的场景模型文件,在网页访问者的客户端逐帧、实时地显示3D图形。互联网3D图形软件厂商目前通常把实时渲染引擎做成一个插件,在观看前需要先下载并安装在IE浏览器上。显然,实时渲染引擎是实施互联网3D图形的关键技术,它的文件大小、图形渲染质量、渲染速度、以及它能提供的交互性都直接反映其解决方案的优劣。

  新一代互联网3D图形的标准——X3D

  X3D标准的发布,为互联网3D图形的发展提供了广阔的前景,无论是小型的具有3D功能的web客户端应用,还是高性能的广播级应用,X3D都应该是大家共同遵守的标准,从而结束当前互联网3D图形的这种混乱局面。在统一的X3D基本框架下保证不同软件厂家开发软件具有互操作性。

  三维建模与Wed3D图形的制作工具

  手工编写VRML的场景模型文件.wrl文件是非常繁琐而复杂的工作,对于大型场景模型几乎是不可能的。近几年,许多软件厂商都使用3DS max建立场景模型,安装相应的输出插件,再直接建立场景模型文件。现在最有名的Wed3D图形软件公司,如cult3D 和viwepoint都可以在3DS max中直接输出它们的专用文件格式的场景模型文件。

  JAVA在互联网上的3D图形的成功

  Java在互联网上几乎随处可见,而它在3D图形上正在显示出更大的威力。使用Java 的重要理由之一是它的平台无关性。因此,只要支持JVM,就能运行JAVA小程序。两种最有名的浏览器Netscape 和 IE 3都支持JVM(Java 1.0.2)。因此用Java制作的3D图形几乎都可以在互联网的浏览器上显示。

  互联网3D图形技术的应用

  当前,互联网上的图形仍以2D图像为主流,但是,3D图形必将在互联网上占有重要地位。互联网上的交互式3D图形技术Wed3D正在取得新的进展,正在脱离本地主机的3D图形,形成自己独立的框架。最具魅力的Wed3D图形将在互联网上有广泛应用,如电子商务、联机娱乐休闲与游戏、科技与工程的可视化、教育、医学、地理信息、虚拟社区

  Wed3D技术发展前景

  虽然,Wed3D技术将有好的发展前景,但仍然不可盲目乐观,它还面临着很多问题,如带宽、处理器速度等。现在的Wed3D图形是有几十种可供选择的技术和解决方案,多种文件格式和渲染引擎的存在是Wed3D图形在互联网上应用的最大障碍,而这种局面还将长时间存在。

VRML—互联网3D图形的开放标准

  VRML是3D图形和多媒体技术通用交换的文件格式,它描述交互式的3D对象和场景。它不仅应用在互联网上,也可以用在本地客户系统中。其应用范围极广:工程和科学可视化,多媒体,娱乐游戏,互联网3D图形,教育,虚拟社区等。在1996年发布VRML1.0。VRML97是最新的国际标准。VRML97的制定促进互联网上的3D图形技术的开发。由于网上传输的是模型文件,故其传输量大大小于视频图像。VRML97使任何一个3D图形爱好者能制作可在互联网上实时渲染的3D场景模型。VRML是基于建模技术的,它描述3D场景中的几何对象的尺寸和形状,色彩,材质,灯光,动画及其交互性。

  然而,在97年之后,VRML3D图形进展缓慢,远远没有达到期望值。究其原因主要有以下几点:

  1 互联网对3D图形的需求并不急切,到目前为止2D图像仍在HTML文件中站主导。
  2 网络带宽仍然是制约网上的3D图形主要瓶颈。
  3 VRML97过于庞大,它包罗万象:3D几何对象,色彩,材质,灯光,相机,动画以及提供交互性的传感器等等。
  4 网站的访问者必须先花费10-15分钟的时间下载插件,然后再像安装软件那样安装这个插件,才能观看一个十分粗糙3D图形。

  图1用VRML制作的法国虚拟巴黎3D场景(可用鼠标实时3D漫游)

形形色色的互联网3D图形软件

  国际上有一个VRML(VRML Consortium)协会,这是一个非赢利组织,主要任务是制定互联网上的3D图形标准与规范。VRML97发布后, 互联网上的3D图形几乎都使用VRML 。VRML协会没有及时推出VRML97的下一代标准。

  最近几年内互联网又有了长足的进展,互联网对图形、图像、视频技术的发展显然有了新的需求,特别是电子商务。互联网上的竞争十分激烈,只要有需求,有利润,就会推进新技术。制作互联网3D图形的软件并没有完全遵循VRML97标准,许多公司推出了它们自己的制作工具,使用专用的文件格式和浏览器插件,类似的软件大约有三十几种之多。这些软件各有特色,都比VRML有了进步,在渲染速度,图像质量,造型技术,交互性以及数据的压缩与优化上有都胜过VRML之处。它们显然都瞄准了电子商务,为网上的电子商品或电子商场提供3D展示。

  这里我们举出一些软件的英文简称:Cult3D,Viewpoint,GL4Java,Flatland,Fluid3D,Janet3D,Java3D,Pulse3D,Shout3D,Sumea,Superscape,Vecta3D,blaxunn3D ,OpenWorlds。所有的公司都希望自己的解决方案能成为"事实上的国际标准"。

  图2 Wed3D的商品展示(商品可用鼠标作3D旋转和细部观看)

  现在的问题是:要在互联网上观看它们的3D图形,先要下载1MB-7MB的插件,然后安装在网页浏览器上(如IE)。这是一件十分烦人的事,插件的种类之多,使人无所适从。要观看十个不同网站,您就要下载并安装十个不同厂家的插件。

互联网3D图形的关键技术——实时渲染引擎

  这些插件就是实时渲染引擎,其作用是:解释并翻译实施场景模型文件的语法,实时渲染从服务器端传来的场景模型文件,在网页访问者的客户端逐帧、实时地显示3D图形。把实时渲染引擎做成一个插件,在观看前先要下载并安装在IE浏览器上,这是互联网3D图形软件厂商目前的通常做法。显然,实时渲染引擎是实施互联网3D图形的关键技术,它的文件大小、图形渲染质量、渲染速度、以及它能提供的交互性都直接反映其解决方案的优劣。

  文件的大小:目前大多数1MB左右,如微软的VRML渲染引擎是1.2M、blaxxun公司的Contact是4.2M、而最小的基于JAVA技术的只有58k。当然,渲染引擎越大,渲染的图像质量就越好,功能就越强大。但下载一个4.2M的插件才能在网上观看3D图形,在目前的网络速度下,仍然是不现实的。

  图形渲染质量: 目前图形质量较好的渲染引擎应该属于cult3D和viewpoint ( 它们的文件尺寸分别是1.4M 和7.9M ) ,使用专用的文件格式。即有较好的图形质量而下载文件尺寸也不大的应该是Parallelgraphics公司的CortonaVRML(1.33M)。

  渲染速度: 支持openGL 或微软的Direct3D 是提高渲染速度和图形质量的关键,在这一点上互联网3D图形与本地3D图形没有区别。

  交互性:交互性是互联网3D图形的最大特色,只有实时渲染才能提供这种交互性,本地3D图形的预渲染不能提供这种至关重要的灵活性。交互性是指3D图形的观看者控制和操纵虚拟场景及其中3D对象的能力,比如:你可以随时改变在虚拟场景中漫游的方向和速度,你可以打开虚拟场景中的门等等。

  研制更好的实时渲染引擎是各软件厂商竞争的焦点,于是就产生了五花八门的3D图形文件格式与相应的浏览器插件。然而VRML毕竟是交互式3D图形开放式国际标准,仍然有很多软件提供对VRML的兼容性。

  结束这种混乱局面的最好办法是微软在它的IE浏览器中预装一个或几个实时渲染插件,以至于互联网3D图形的观看者不必花费10分钟的时间去下载插件。然而,微软并未选中任何一家公司作为其合作伙伴,也许在某一天微软会推出它自己的一整套解决方案,从而保持它在互联网3D图形领域中的霸权地位。

新一代互联网3D图形的标准——X3D

  VRML(VRML Consortium)协会在1997年将它的名字改为Wed3D(Web 3D Consortium)协会,并制定了VRML97新的国际标准。此后Wed3D这一专用缩写开始在互联网上出现。然而,1997年后的几年,该协会并没有什么大的动作。直到去年(2001年)8月Wed3D协会发布新一代国际标准—- X3D (X3D的含义是可扩展的 3D)。

  X3D是Wed3D协会(Wed3D Consortium)制定的下一代VRML97标准。X3D是在重要软件厂商的支持下提出的,如3Dlabs, ATI Technologies, Blaxxun, Nexternet, OpenWorlds, ParallelGraphics, Sony Electronics, US Army STRICOM, and SGDL Systems 。X3D与MPEG-4和 XML兼容。X3D将集成到MPEG-4的3D内容之中,使用XML语法。它与VRML 97向后兼容,即X3D能提供标准VRML 97 browser的全部功能。X3D的主要任务是把VRML的功能封装到一个轻型的,可扩展的核心之中。由于X3D是可扩展的,任何开发者可以根据自己需求,扩展其功能。X3D 渲染引擎的商业版本也在去年的SIGGRAPH 2001的年会上推出,ParallelGraphics(Wed3D技术的领先软件公司)将联合几个公司开发X3D 新技术。X3D标准的发布,为互联网3D图形的发展提供了广阔的前景,无论是小型的具有3D功能的web客户端应用,还是高性能的广播级应用,X3D都应该是大家共同遵守的标准,从而结束当前互联网3D图形的这种混乱局面。在统一的X3D基本框架下保证不同软件厂家开发软件具有互操作性。

  在SIGGRAPH 2002会议上Wed3D Consortium发布X3D最终工作草案。Wed3D Consortium希望Wed3D软件公司使用X3D规范开发相应的产品评估规范的可行性。Wed3D Consortium准备将该规范递交给国际标准化组织ISO。

三维建模与Wed3D图形的制作工具

  VRML是一种标记语言,任何文字编辑程序都可以编辑VRML的场景模型文件(其扩展名是.wrl)。手工书写.wrl文件是非常繁琐而复杂的工作,对于大型场景模型几乎是不可能的。为了制作Wed3D图形的场景模型文件必需使用传统的三维建模软件。近几年,许多软件厂商都把3Dmax作为三维建模与场景的制作工具。使用3Dmax建立场景模型,安装相应的输出插件,即可以直接建立场景模型文件。现在最有名的Wed3D图形软件公司,如cult3D 和viwepoint都可以在3Dmax中直接输出它们的专用文件格式的场景模型文件。如前述,每个公司都有自己的文件格式和相应的实时渲染插件,同样,也有它们自己的制作工具。

  Wed3D图形的制作工具及实用程序五花八门难以详述,但是它们的功能一般都包括:

  1 建立或编辑三维场景模型
  2 增加或改进Wed3D图形的图像质量
  3 增加Wed3D图形交互性
  4 压缩或优化场景模型文件的大小
  5 文件加密

  三维建模是Wed3D图形制作的关键,而所用的成本是比较高的,例如:如果您要制作一个较高质量的3D手表模型,专业人员要花费40小时建模,价值几万元。大型建筑场景则需要更多的工作量。为解决这个问题,近几年国外出现一种新的建模技术:照片建模技术。对建模对象实地拍摄两张以上的照片,根据透视学和摄影测量学原理,标志和定位对象上的关键控制点,建立三维网格模型。近年已有商品化软件推出,如Canoma,Photo3D,PhotoModeler,ImageModeler等。此类软件的技术要点如下:

  1 寻找和标识建模对象关键点:复杂曲面则需要数量较多的关键点。
  2 拍摄1—4张以上的照片:相机的位置不限,但关键点要拍摄清晰。
  3 把拍摄的照片输入到软件中,使用软件提供的手段定位关键点,构建三维网格模型。
  4 把照片上拍下的2D图像作为材质贴图贴在模型的表面
  5 把已建好的模型输出成相应的文件格式,如VRML

  MetaCreations公司的Canoma是比较早推出的软件,适用于由直线构成的建筑物。
  REALVIZ公司的ImageModeler(价格5000$)是第二代产品,可以制作复杂曲面物体。

  与大型3D扫描仪比较,这类软件有很大的优势:使用简单,节省人力,降低成本。ImageModeler已经被Cult3D用于建模工具。

  最近,3D studio max软件的制作厂家Discreet推出了一款直接面向Wed3D的制作软件—-Plasma,Discreet看到了Wed3D市场的巨大商机,凭借3D studio max的市场优势,相信: Plasma市场前景看好。

JAVA在互联网上的3D图形的成功

  Java在互联网上几乎随处可见,而它在3D图形上正在显示出更大的威力。使用Java 的重要理由之一是它的平台无关性。它的平台无关性来自于Java只需部分编译,负责编译Java程序的叫做Java Virtual Machine (JVM),不同的平台有它自己JVM,处理与平台相关的功能。因此,只要支持JVM,就能运行JAVA小程序。两种最有名的浏览器Netscape 和 IE 3都支持JVM(Java 1.0.2)。因此用Java制作的3D图形几乎都可以在互联网的浏览器上显示。

  令人遗憾的是:微软在它的未来极具发展前景的Window XP中不再预装JVM,由此引起的麻烦是巨大的:要运行基于JAVA的应用,就必须安装JVM,这显然比安装一个插件更麻烦。

  由于全世界有90%的人上网使用微软不要钱的浏览器IE,而Wed3D的渲染引擎插件又必须安装在IE上。面对Wed3D技术未来的发展潜力,软件巨人微软作何打算我们不得而知。

  Shout Interactive and Blaxxun两个公司使用纯Java技术开发了实时渲染引擎(大小只有50K),这个小小的JAVA小程序,不仅在网上自动下载,而且可以在客户端实时渲染3D场景,逐帧显示动态的3D图像。Shout Interactive and Blaxxun为用户扩充自己的3D图形功能预留了极大的空间。两个公司并没有抛弃VRML,Shout Interactive公司可以接受VRML文件,并把它变成自己的文件格式,Blaxxun公司的软件可以直接运行VRML。当然,Shout 3D的小巧灵活并不是没有代价的:它简化了VRML的功能,VRML的一些功能不能用小小50K的Java来实现。可以说这两个公司最先在它们的产品中实现了核心的X3D技术。

  使用这种"无插件技术"(plug-in)的Shout公司为Macy’s and Excite web portal网站制作了栩栩如生如生的3D虚拟时装模特展示,观看者用菜单可以选择:展示的服装,模特的肤色,发型,步型,甚至于灯光都可以用菜单即刻更换。观看者可以用鼠标变换视角,远近,从各个角度观看动态展示。而所有的展示文件只有1M-2M,不需下载插件。图像的质量较好,人物动画的动作流畅自然。

  图3 用shout3D 的java技术制作的3D服装展示

互联网3D图形技术的应用

  当前,互联网上的图形仍以2D图像为主流。但是,3D图形必将在互联网上占有重要地位。互联网上的交互式3D图形技术— Wed3D正在取得新的进展,正在脱离本地主机的3D图形,而形成自己独立的框架。互联网的需求是它发展的动力。互联网的内容提供商和商业网站不断使用新的工具与技术使网站更具吸引力,Wed3D图形是最新的和最具魅力的技术。Wed3D图形将在互联网上有广泛应用,从目前的趋势来看主要有:

  1 电子商务:用3D图形展示商品,更能吸引客户。虚拟商场是人们热中的话题。客户可以在虚拟商场中漫游,挑选商品。许多Wed3D图形技术的软件厂商是瞄准了电子商务的,如cult3D和viewpoint,其图形技术主要是用于商品的3D展示,您甚至于可以在网上操作或使用要购买的商品。然而,Wed3D图形的商业利益究竟有多大,网上的商品销售商只有在能增加销售额的情况下,才肯出资制作Wed3D图形。

  2 联机娱乐休闲与游戏:多用户联机3D游戏将搬上互联网,现在您已经可以在网上经历简单的赛车或空中射击游戏,下载文件不超过2M。当然,如果您想运行大的联机游戏仍然需要CD-ROM的支持。娱乐休闲网站对Wed3D图形有更多的需求,如:城市景观或风景点的虚拟旅游,虚拟博物馆,展览会,艺术画廊等等。

  3 科技与工程的可视化:科普,工程演示,城市建设,建筑装修。

  4 教育:学校,培训,军事训练,可视化仿真。

  5 医学:医疗培训,医疗商业的B2B和B2,许多医学图像的处理将使用Wed3D图形技术。

  6 地理信息系统的数据可视化:将GIS与Wed3D结合起来,可以在互联网上建立许多应用系统,如地图,导游,城市建设,交通运输等等。

  7 多用户虚拟社区(virtual-community):虚拟社区是建立一个大型的虚拟场景,每个虚拟场景的访问者都可以指定一个"替身", "替身"在场景中可以漫游。当几个远程访问者同时访问虚拟社区时,它们可以用语音或文字通讯。虚拟社区可以是一个会场,教室,俱乐部,展览会,画廊等。它真正实现了虚拟现实,在互联网上仿真虚拟社会的各种活动,分布在世界各地的人可以借助互联网开展各种文化科技,娱乐活动。而此时虚拟场景就是他们的三维环境。虚拟社区很可能是Wed3D图形在互联网上的一种主要应用形式。

  现在,已有几家公司推出了自己虚拟社区及全套的解决方案,如Blaxxun, Adobe Atmosphere. Geometrek ,Cybertown, OuterWorlds, berkom ,ActiveWorlds,iCity,pointworlds等。它们除了提供虚拟场景制作以外,还提供:服务器管理,通讯管理,用户管理等功能。Blaxxun公司Virtual Worlds Platform 5.1服务器已经有许多网站用它建立虚拟社区。

  图4 Cybertown虚拟社会首页

  Cybertown是目前世界上规模最大的虚拟社区,它有近200个虚拟场景,几百万人在这个虚拟社会中居住,安家。它有完整的社会管理体系,各类公用设施:商店,俱乐部,职业介绍所,体育馆,公园,跳蚤市场,市政大厅,咖啡厅,画廊等等。您可以在这个虚拟城市中购置房地产,寻找工作,娱乐,学习。您可以结交世界各个角落不同国籍的朋友,与他们会见,谈话(语音或文字),交流各种信息。Wed3D技术将把虚拟社会变成现实,借助于互联网,居住在地球上人们的距离一下子拉近了。

Wed3D技术发展前景

  虽然,Wed3D技术将有好的发展前景,但仍然不可乐观,它面临下述问题:

  网络带宽仍然是Wed3D主要瓶颈:当前处理器的速度与网络的带宽只能初步满足Wed3D图形联机操作的要求,随着 Cable modems 和 DSL 连接的应用,网络带宽将有更大的改进,当一个10MB左右的Wed3D模型文件只需要几秒钟下载时,Wed3D图形的质量将有很大的改善,而现在的带宽还不能满足要求。

  Flash作为2D动画在互联网上的成功的关键是只有唯一的技术和标准。现在的Wed3D图形是有几十种可供选择的技术和解决方案,多种文件格式和渲染引擎的存在是Wed3D图形在互联网上应用的最大障碍,而这种局面在今后若干年还将存在。

  从现在的发展态势来看,有几种技术可能在未来有一定的优势:

  X3D:由Web 3D Consortium制定,得到大学,政府机构及一些Wed3D图形公司的支持,由于它是VRML97下一代新的国际标准,有比较广泛的社会基础。
  Pulse3D:在游戏娱乐领域内领先,使用它的技术的游戏网站有100多个,它得到Discreet 和Entertaindom公司的资金支持,现在它正在把游戏领域的技术优势应用到e-commerce。它的插件支持QuickTime 5 and RealPlayer。
  Viewpoint:前身是MetaCreations(3D图形应用软件开发商),它卖掉了所有的其他软件产品,改名为Viewpoint,专们从事Wed3D图形技术。其渲染引擎的模块化结构极易扩充,并且能与QTVR-, iPix-, and XML-等标准集成。它的目标是e-commerce。它的技术的最大特色是与XML集成。
  Cult3D:开发了e-commerce的全套解决方案,已经有450 e-commerce网站使用了 Cult3D技术,近10000个商业模型,它也在向娱乐领域扩充,提供全面解决方案,提供最稳定可靠的渲染引擎
  Shockwave3D: 这是Macromedia公司Flash插件,有着极为广大的用户群(据说世界上有1亿3千万人安装),更引人注目的是Intel把它的Wed3D 图形集成到Shockwave。IntelWed3D图形极具特色:动态调节3D内容的分辨率,曲面光滑技术,照片级逼真材质及各种特色效应。

  在今年的SIGGRAPH 2002世界计算机图形会议上,Intel宣布建立Wed3D/CAD工作组, 其主要目标是:建立一个统一的,开放的文件格式,用于在Web上显示实时的3D图形。与此同时Wed3D Consortium在SIGGRAPH 2002会议上了发布X3D最终工作草案。X3D是一个成熟的标准,是VRML的下一代标准,但是Intel完全没有提到它,如果Intel重新制定另外一个新标准,X3D的将面临尴尬,就Intel公司的实力和威望,X3D很难成为真正的国际标准。Intel公司很可能将左右新标准的制定与推行。

  预测未来谁是最后的胜利者是困难的,也许很长一段时间内将是多种技术同时共存而又相互竞争。而Intel和微软都具有左右Wed3D发展前景的实力。

  现在我们应该思考一下,我们国内应该如何发展我们自己的Wed3D图形技术?

分类: 其他 标签:

HTML5 Web SQL Database 对象本地持久化

2010年5月30日 没有评论

       HTML 5标准并不只局限于传统的标记语言,它还拥有很多让人期待的API接口,利用这些接口,开发者可以创建更加丰富、更加引人注目的应用程序。之前我们介绍过支持文件拖放上传功能的HTML 5 File API,今天,我们一起来了解HTML 5的Web SQL Database API,使用本地和会话存储实现简单的对象持久化。

  对于HTML 5,也许最为有用的就是它新推出的“Web Storage”(Web 存储)API。对简单的关键值对(比如应用程序设置)或简单对象(如应用程序状态)进行存储,使用本地和会话存储能够很好地完成,但是在对琐碎的关系数据进行处理之外,它就力所不及了。而这正是 HTML 5 的“Web SQL Database”API 接口的应用所在。

      近日Google宣布将支持HTML 5 Web SQL Database API,其他浏览器厂商也表示将紧随其后提供该支持,有的甚至已经开始支持该API了;但同时,HTML 5规范的制订却遇到了阻碍,因为所有的参与者都已选择了SQLite作为底层数据库,要想实现标准化还得考虑多个不同的实现。

      作为HTML 5的一部分,W3C组织正在制订Web SQL Database API草案,该规范主要用于解决如何通过SQL存储及访问数据的问题。文档中所使用的SQL语言是SQLite 3.6.19。网页可以使用这个API与嵌入式的客户端数据库进行交互,这对于那些想要在本地存储数据或是离线浏览的应用来说价值非常大。

      Google已经在其最新的浏览器Chrome 4中通过SQLite提供对Web SQL Database的支持了,这个举动可以看作是向标准化迈进的一大步,因为Google Gears中已经拥有了一个Database API,也是基于SQLite。Gears API为所有主流浏览器提供了结构化的数据存储功能,包括IE、Firefox以及Safari,但现在Google已经停止Gears的开发工作了。

      Firefox 3拥有一个嵌入式SQLite数据库,目前主要用于存储书签和历史记录,但可能不久后就将支持Web SQL Database API。当前的开发工作正在WebKit(Safari所用的渲染引擎)上进行以向Web开发者提供Web Database API。现在谁也不知道微软对于IE和HTML 5 Database API的计划到底是什么。

  先提个醒,该文下面的内容需要读者对 JavaScript 和面对对象编程(尤其是匿名内的内部函数)以及SQL具有很好的理解。

  打开链接

  为了打开一个连接,我们执行以下代码:
db = openDatabase("ToDo", "0.1", "A list of to do items.", 200000);

  以上代码创建了一个数据库对象 db,名称是 Todo,版本编号为0.1。db 还带有描述信息和大概的大小值。用户代理(user agent)可使用这个描述与用户进行交流,说明数据库是用来做什么的。利用代码中提供的大小值,用户代理可以为内容留出足够的存储。如果需要,这个大小是可以改变的,所以没有必要预先假设允许用户使用多少空间。

  为了检测之前创建的连接是否成功,你可以检查那个数据库对象是否为null:
if(!db) alert("Failed to connect to database.");

  绝不可以假设该连接已经成功建立,即使过去对于某个用户它是成功的。为什么一个连接会失败,存在多个原因。也许用户代理出于安全原因拒绝你的访问,也许设备存储有限。面对活跃而快速进化的潜在用户代理,对用户的机器、软件及其能力作出假设是非常不明智的行为。比如,当用户使用手持设备时,他们可自由处置的数据可能只有几兆字节。

  执行查询

  执行一个查询,你可以使用database.transaction()函数。该函数具有单一参数,负责查询实际执行的函数。

  该函数(通常是匿名的)具有一个类型事务的参数。

  db.transaction( function(tx) { 该事务具有一个函数:executeSql。这个函数使用四个参数:表示查询的字符串,插入到查询中问号所在处的字符串数据(很像 Java 的预先准备好的语句),一个成功时执行的函数和一个失败时执行的函数。
tx.executeSql("SELECT COUNT(*) FROM ToDo", [], function(result){}, function(tx, error){});

  查询成功时

  当查询成功执行时,应用程序跳转至一个具有一对参数的查询,一个是 transaction,另一个是它搜集的 results。对于实际上将你的数据传递至用户,这是非常完美的,比如显示 ToDo 列表。有关这个话题后面再讲。

  查询失败失败时

  当查询没能执行时执行。由于你将 transaction 对象作为函数的第一个参数进行传递,当出现错误时你可以继续执行查询。例如,如果是因为缺少表格(table)而查询无法运行,这是创建一个表格并在此执行该语句的绝佳时机。从该函数的第二个参数,你可以获得有关该错误的信息(包括描述)。

  示例

  假设我们想要使用上面的例子,想要查询数据库中的某个表格,如果该表格不存在,我们就创建一个表格。

  在这个示例中,我们将调用具有一个函数参数的 db.transaction()。这个参数中,我们调用 tx.executeSql()。如果这个步骤成功,我们不做任何操作(因此是一个null参数)。或者我们将该事务和执行失败的函数一起传递,并再次调用 tx.executeSql()。这一次使用创建查询。
db.transaction( function(tx) { tx.executeSql("SELECT COUNT(*) FROM ToDo", [], null, function(tx, error) { tx.executeSql("CREATE TABLE ToDo (id REAL UNIQUE, label TEXT, timestamp REAL)", [], null, null); } ); } );

  使用所有这些内部方法,可能有点麻烦,所以你也许想在外部创建一个调用 db.transaction() 的函数。比如,我们可以让错误函数是自包含的,并将其命名为“createToDoTable()”。

  插入

  为了让代码更加简洁和安全,Web SQL Database API 允许你为 transaction.executeSql() 函数提供字符串数据,用以表示调用的 SQL 语句中的变量。我们使用以下的代码进行演示:
db.transaction( function(tx) { tx.executeSql("INSERT INTO ToDo (label, timestamp) values(?, ?)", [label, new Date().getTime()], null, null); } );

   在这个示例中,第一个参数中的两个问号将被后面数组中对应的项替代。第一个是为该任务设置的标签(也许是我们之前在代码中定义的一个变量),以及调用函数生成的时间戳。

  执行该查询,其结果与下面语句类似:
INSERT INTO ToDo (label, timestamp) values ("Test", 1265925077487)

  对结果进行处理

  成功执行的函数对结果对象包含集合或行。每一列表示一个结果。该结果包含分配给它的一组值,表示该特定结果的数据库中的每一列的值。通过调用 result.rows.item(i) 可以访问一个行,其中 i 是你想要查询的行的指针。想要从一行中选择一个值,你可以传递给该行一个数组格式的字符串指针,它表示你需要查询的列。例如,如果想要标签(label)列,我们可以调用 row[‘label’]。

  以下代码使用结果对象来输出一个查询的结果:
db.transaction( function(tx) { tx.executeSql("SELECT * FROM ToDo", [], function(tx, result) { for(var i = 0; i < result.rows.length; i++) { document.write(” + result.rows.item(i)[‘label’] + ‘
‘); } }, null); } );

  结论

  需要注意的是,如果不是绝对需要的情况,不要使用 Web SQL Database。这不是因为它们的技术高高在上,而是因为它们会让你的代码更加复杂。对于大多数情况,本地存储或会话存储就能够完成相应的任务,尤其是你能够保持对象状态持久化的情况。

  正如前面所说,通过这些HTML 5 Web SQL Database API 接口,你可以获取许多功能。我相信,几年以后会出现一些非常优秀的、建立在这些 API 之上的应用程序。

分类: 其他 标签:

MusicAPI & Music MashUp-音乐API 和音乐应用聚合

2010年5月27日 没有评论

无论你是一个歌手或是一个音乐爱好者,现在有许多音乐应用程序接口可以为你所用。Last.fm 是网络中最流行的一个。他的API提供了Last.fm中会员、艺术家、专辑、音轨等诸多数据。目前已经发布了超过36个 Last.fm应用聚合 ,并且这一列表仍在不断增长中。随着最近新增的LyricsFly API和它的拥有314000首歌的歌词数据库,目前已经有25个 音乐APIs 在ProgrammableWeb目录中(还有135 个已发布的聚合应用

Last.fm不过是其中的一个例子。这些应用程序接口(API)帮助你发现那些你喜欢的音乐,提供给你与音乐相关的,包含所有细节的原始数据,还可以让你在线保存和管理你的音乐。另外一些API提供在线的广播和音乐订阅服务。这些API可用来定制音乐播放器,寻找现场的音乐,甚至帮你销售你的音乐作品。许多已经在ProgrammableWeb中增加的专门的栏目去跟踪他们:Music API and Mashup Dashboard

Managing Your Music管理你的音乐

管理你的音乐收藏不再只是意味着将你的CD按照一定循序进行排列。今天,我们可以在不同的地方使用不同的设备来欣赏音乐,这也使我们很容易忘记把喜欢的音乐放在了什么地方。另外,音乐可以无处不在,但是你怎么才能按照你喜欢的方式找到他们呢?

这是开发人员尝试用音乐API来解决的一个关键问题。

Music Discovery 音乐发现

如何能够找到你喜欢的新的音乐作品?如何把它放入到我的收藏,并进行合理的管理归类以便我以后还能找到它?除了我们已经探讨过 Last.fm,当然还有许多别的也不错的解决方案。

类似 Last.fm,OpenStrandsAPI 提供一套Web2.0的方式来发现音乐:API提供一种可编程的方式来访问MyStrands.com社区的推荐、标签和播放列表服务。另外音乐搜索工具中包括了一个数字播客 API-可以让你通过 关键字来查找音乐 , SeeqPod API(多媒体搜索)-可以输入你喜欢的歌曲名字,API将返回一个歌曲列表,Yahoo Audio Search API-通过结构化和非结构化的查询音频文件和相关的音乐数据。

特别值得一提的是 MusicDNS API:它能自动用一些运算法则将你的音乐与它数据库中的音乐进行比较,从而识别那些艺术家的风格与你的相近。

About the Music (Music Metadata) 音乐信息(音乐原始数据)

如果你找到的一些你喜欢的音乐,你可能希望了解更多的关于歌曲或、作者和歌手的相关信息。一些API是提供音乐相关信息的原始数据。Freedb / CDDB提供音乐CD的相关信息:表演者、CD标题、音轨清单和其他信息。最有趣的是你想找的信息可能就在你计算机的CD驱动器中那张CD上,或者其他Freedb 兼容的设备上。

MusicBrainz API, Tunelog APIDiscogs API都提供一些 Web2.0的方式,提供对大型音乐原始信息数据库访问,这些数据库都依赖于或基于 MusicBrainz, Tunelog和Discogs 社区的集体维护。

Media Management and Online Broadcasting 媒体管理和在线广播

一些帮助你管理音乐的API。 Faces.com APIIpernity API 让你可以和朋友以及网站上其他会员分享音乐、照片和视频。

今天我们可以与通过广播完全不同的方式,分享你的媒体资料。但是许多网站更喜欢广播的方式,这意味着内容更专业一些。Orb API允许你广播你的音乐、视频和照片,等等。 RadioTime API能够让你找到并欣赏全球超过60,000 个广播站。

Rhapsody API和音乐订阅服务让你可以管理你的狂想曲列表,搜索音乐和访问你的狂想曲RSS聚合。

Music Players 音乐播放器

Yahoo Music Engine API, Winamp API, 和 MP3Tunes API 都提供通过代码定制他们的音乐播放器的功能。

Music Events 音乐大事件

当听完一个新人的旋律,你可能想要看他们的表演。Eventful API, JamBase APIGruvr API可以让你搜索到演唱会和其他相关事件。Eventful 更进一步满足的你需求,可以让你了解到哪个艺人在你所在的地区露过面,Gruvr的API让你可以整合现场音乐地图和演唱会日历在你自己的网站上。

APIs For Performers 为表演者提供的API

如果你是一个表演者,那么你一定对下面的API看兴趣。你可能希望你的作品让所有人听到和搜索到。你希望把你的歌提交到MusicDNS.org,以便那些喜欢你这种音乐风格的人更容易地发现你的新作。你可以用 Eventful, JamBaseGruvr提供的API来作为你宣传推广的表演日历。最后如果你打算销售你的录音带,研究一下SNOCAP API,可以帮助你建立你自己的音乐商店。

Music Mashups 音乐应用聚合

音乐 API提供了多种多样的音乐应用聚合的可能。其中在我们的音乐应用聚合名单中比较早表较流行的就是MusicPortl,一个通过网络收集某些演艺人士的信息,为包括传记、照片、相册、视频和Blog等内容建立一个页面。MusicPortl通过7个不同的API来提供这些信息,包括Amazon eCommerce API, Flickr API, Last.fm API, MusicBrainz API, Ontok API, Technorati APIYouTube API

许多音乐应用聚合了互联网上演艺人员的数据到一个统一的搜索接口,其中有FoxyTunes。这个月的早些时候你可以在这了列表里看到。

这里有135 个已发布的音乐应用聚合名单,其中表较流行的有:TuneGlue, ZonTube, KEXPlorer.com, MusicTonic, One Hit Wonders Map, JukeboxTube, Indie Tube, NPR Station Map 和音用聚合竞赛优胜者PodBopthe Hype Machine

摘要

现在,有相当多的多种多样音乐API已经发布,这一数量还在不断增长中。点击这里更新当下可用的音乐API列表

分类: 其他 标签:

百度MP3音乐API接口及应用

2010年5月27日 没有评论

      当你在百度去搜索一首歌时,你会发现有种更简单的方法,嘿嘿,安宁ヤ太天真告诉你个秘密,百度有个不公开的API

http://box.zhangmen.baidu.com/x?op=12&count=1&title=大约在冬季$$齐秦$$$$
用上面的地址,红色部分改成歌名与作者名,然后百度就会给你一个XML:
<?xml version="1.0" encoding="gb2312" ?>
<result>
  <count>1</count>
<data>
<encode>http://song.feifa-radio.com/Q/20050701/jingxuan/YjI$.Wma</encode>
<decode>1.Wma</decode>
<type>2</type>
<lrcid>49684</lrcid>
   </data>
</result>

其中的count 值为1是说返回的是一个,这个没什么用,接下来的东西就有用了,encode里的值是歌曲加密后的地址,加密只是对文件名加密的,我们需要的只是前面的路径,也就是 http://song.feifa-radio.com/Q/20050701/jingxuan/ 这部分,然后复制decode 的值: 1.Wma 与前面的相拼就是正确的下载地址:
http://song.feifa-radio.com/Q/20050701/jingxuan/1.Wma
后面的type的值为2表示此歌曲文件类型是wma的,其它的:1表示rm,0表示MP3,通常我们下的类型都是MP3或WMA的,所以只要有2或0的
lrcid这个的值是百度服务器上这首歌的歌词文件的文件名,这个文件的路径是:http://box.zhangmen.baidu.com/bdlrc/496/49684.lrc  

这个地址解析下:
http://box.zhangmen.baidu.com/bdlrc/ 这个是百度lrc歌词存放地址,后面的496是一个的不定的,民就是说歌曲不同那个目录名也不同,它的算法是拿歌词文件名(也就是上面说的 49684) 除以一百,然后取小于等于其结果的最大整数,如上面的:49684/100 =496.84 小于等于496.84 的最大整数就是496,于是这首歌完整的歌词地址就出来了:http://box.zhangmen.baidu.com/bdlrc/496/49684.lrc

安宁ヤ太天真似乎说得复杂了了,呵呵,希望对大家有用

作者: 安宁ヤ太天真
网址: http://hi.baidu.com/kiss3344
版权所有。转载时必须以链接形式注明作者和原始出处及本声明。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Xml;
using System.Windows.Forms;

namespace BaiDuAPI
{
   public partial class Form1 : Form
   {
       public Form1()
       {
           InitializeComponent();

           this.skinEngine1.SkinFile = "vista1_green.ssk";
       }

       private void button1_Click(object sender, EventArgs e)
       {
           System.Media.SoundPlayer sp = new System.Media.SoundPlayer();

           

           try
           {
               string strEncode = "";

               string strDecode = "";

               string strLrc = "";

               string strExt = "";

               string strPath = "";

               string[] AppString;

               string AppAPI = GetMP3URL(textBox4.Text);

               if (AppAPI == "nothing")
               {
                   MessageBox.Show("找不到音乐 " + textBox4.Text + " 请更换查询名称");

                   return;
               }
               else
               {
                   AppString = AppAPI.Split(" ".ToCharArray());

                   strEncode = AppString[0].ToString();           //编码

                   strDecode = AppString[1].ToString();           //解码

                   strExt = AppString[2].ToString();              //扩展名

                   strLrc = AppString[3].ToString();              //歌词URL

                   strPath = AppString[4].ToString();             //歌曲URL

                   textBox1.Text = strEncode;

                   textBox2.Text = strDecode;

                   textBox3.Text = strPath;

                   textBox5.Text = strExt;

                   textBox6.Text = strLrc;
               }
           }
           catch
           {
               MessageBox.Show("找不到音乐 " + textBox4.Text + " 请更换查询名称");
           }

       }

       public string GetMP3URL(string fString)
       {
           try
           {
               string strAPI = "http://box.zhangmen.baidu.com/x?op=12&count=1&title=";

               strAPI = strAPI + fString;

               XmlTextReader hfXMLReader = new XmlTextReader(strAPI);

               DataSet ds = new DataSet();

               ds.ReadXml(hfXMLReader);

               string strDecode = ds.Tables["data"].Rows[0]["decode"].ToString().Replace("\n", "");         //读取歌曲名称

               string strEncode = ds.Tables["data"].Rows[0]["encode"].ToString().Replace("\n", "");       //读取歌曲编码

               string strLrc = ds.Tables["data"].Rows[0]["lrcid"].ToString().Replace("<br />", "");             //读取歌词ID

               string strPath = "";

               string strExt = "";

               string[] strPre = strEncode.Split("/".ToCharArray());

               strPath = strEncode.Replace(strPre[strPre.Length – 1], strDecode);         //赋值MP3真正地址

               string strLrcPath = "http://box.zhangmen.baidu.com/bdlrc/";                //歌词基本地址

               if (strLrc == "0")
               {
                   strLrc = "暂无歌词";
               }
               else
               {
                   strLrc = strLrcPath + (Int32.Parse(strLrc) / 100).ToString() + "/" + strLrc + ".lrc";
               }

               switch (ds.Tables["data"].Rows[0]["type"].ToString())
               {
                   case "1":
                       strExt = "rm";
                       break;
                   case "0":
                       strExt = "mp3";
                       break;
                   case "2":
                       strExt = "wma";
                       break;
               }

               if (strEncode == "nothing")
               {
                   return "nothing";
               }

               return strEncode + " " + strDecode + " " + strExt + " " + strLrc + " " + strPath;
           }
           catch
           {
               return GetMP3URL(fString);
           }
       }

       private void button2_Click(object sender, EventArgs e)
       {
           string tempstr = "";

           for (int i = 1; i < 11; i++)
           {
               tempstr += "1<<" + i.ToString() + ": " + (1 << i).ToString() + "\r\n";
           }

           MessageBox.Show(tempstr);
       }

       private void button2_Click_1(object sender, EventArgs e)
       {
           this.axWindowsMediaPlayer1.URL = textBox3.Text;
       }
   }

原文:http://shuhejiang.blog.163.com/blog/static/117667532009111533750457/

分类: 其他 标签:

同时使用svn+git进行版本管理

2010年5月26日 没有评论

项目环境说明

项目使用svn进行代码版本管理。

使用场景

修改了某些文件后,在修改成另外的实现方法前先备份当前已经实现的方案(git commit临时文件)

在不能连接svn服务器的机器上修改svn版本管理的代码,且需要进行版本管理

前期准备

安装git(MSsyGit,TortoiseGit)

安装svn(TortoiseSVN)

测试步骤

本地新建目录 welkinvcproject.svngit,svn checkout file:///E:/Code/svnRepository/welkinvcproject/trunk

在svn Settings的Global ignore pattern增加*.git,例如我的设置是*.git *.obj *.manifest *.manifest.res *.ilk *.idb *.dep *.user *.exe *.pdb

在 welkinvcproject.svngit目录鼠标右键点击Git Init Here

在welkinvcproject.svngit目录下建立.gitignore文件,把不需要git管理的文件加入此表,例如.svn. 或者编辑.git/info/exclude文件,我设置的是

*.svn

*.obj

*.manifest

*.manifest.res

*.ilk

*.idb

*.dep

*.user

*.exe

*.pdb

在welkinvcproject.svngit目录鼠标右键点击Git Commit -> "master"…,提交所有svn版本控制的文件

在本地随便修改几个文件,但由于还不能确定是最后的代码,所以不能提交到svn,采取临时提交到git的办法来管理。在welkinvcproject.svngit 目录鼠标右键点击Git Commit -> "master"…,提交变更的文件

重复循环执行上一步

最后再提交到svn,再提交到git,这是svn 的代码和git的代码是一致的。(稍后如果发现之前提交到git的某个版本的代码更合适,可以使用git revert到相应的版本,再提交到svn和git)

原文: http://wengshanjin2001.blog.163.com/blog/static/376284582010018101535344/

分类: 其他 标签:

浅析豆瓣的 Google Analytics 应用

2010年5月25日 没有评论

      关于这篇文章我觉得豆瓣在使用Google Analytics 自定义参数的使用上面还是值得借签的,除了频道流量分析,还有登陆用户跟踪也是一个亮点,对用户行为跟踪分析,不公能够实现全局跟踪,而且可以达到精确到单个用户.

      豆瓣 Google Analytics 代码加载模式

      豆瓣从今年开始也加入 Google Analytics 的统计阵营。让我们通过它加载的 Google Analytics 源码,简单分析一下它都是怎么应用的。

我们先从豆瓣的源码来看看它的Google Analytics统计代码

豆瓣 Google Analytics 代码

我们知道一般默认的 Google Analytics代码如下:

默认 Google Analytics 统计代码

      两相对比,我们就会发现豆瓣加载 ga.js 的方式与默认的方式有些不太一样,由于豆瓣并没有采用 https 加密访问,所以撇弃了默认的ga.js加载方式。

      默认的统计函数,pageTracker 也被豆瓣改成了 _ga ,这个只是名称定义上的区别,并没有什么实质的改变。豆瓣的主要应用是下面两个函数:

使用 _ga._addOrganic 识别非主流搜索引擎

       再来看豆瓣比默认 Google Analytics 代码增加的部分,那就是多了数个 _ga._addOrganic ,这是 Google Analytics 添加自定义搜索引擎的代码。尽管 Google Analytics 对于主流的搜索引擎都能自动识别,但毕竟能识别的是国外的主流搜索引擎,在国内,像搜狐的 Sogou,QQ 的 soso,网易的有道等搜索引擎,都不能被 Google Analytics 正确识别,而被当作推荐来源。这时候我们就可以利用_addOrganic 参数来识别这些非主流搜索引擎,如豆瓣的做法。

使用 _addIgnoredOrganic 忽略关键字

除了添加自定义搜索引擎,豆瓣在最后还添加了如下这些代码:

_ga._addIgnoredOrganic("豆瓣");
_ga._addIgnoredOrganic("douban
_ga._addIgnoredOrganic("豆瓣网
_ga._addIgnoredOrganic("www.douban.com");

这些代码用来把引号中的关键词从搜索引擎的关键词报告中排除,而当成直接点击量来源。

       为什么要这么做?因为一个知名的大网站,来自这些品牌词的搜索流量都非常大,常常是排在前几位的搜索关键词来源,而这通常是因为搜索引擎养成现在的人都懒得记网址,直接搜索品牌名来记住域名。这些品牌词对于网站的关键词来源分析并没有很直接的帮助,所以在来自品牌词的流量很大的情况下,可以直接把这些关键词识别成直接点击量来源。

关于自定义 Google Analytics 搜索引擎和排除特定关键词为直接点击量来源的语法,可以参考 Google Code 上关于这方面的详细介绍

通过 _setVar 识别用户

当我们登录豆瓣后,再来分析豆瓣的源码,会发现多了一个ga._setVar(”xxxx”)的 Google Analytics 参数。

豆瓣使用 Google Analytics 的._setVar参数来跟踪登录用户行为

      _setVar() 函数是 Google Analytics 的用户定义函数,主要用于对特定来源的用户行为进行分类,例如可以对登录浏览的用户设置一个数值,然后在 Google Analytics 后台的访问者/用户定义 中查看其浏览属性。

Google Analytics 访问者/用户定义报告

      分析豆瓣的源码可以知道,豆瓣对每一个登录后的用户,都赋以一个专门的 id 值,这样可以在用户定义报告里,看到整体的登录用户访问行为,乃至每个登录用户的浏览行为。通过这样设定后,豆瓣便可以轻易获取高忠诚度访问用户的访问行为。关于_setVar()的更多说明,请参阅 Google Analytics的技术文档

      如何根据访问者在我的网站上访问的页面或在表单上做出的响应对其进行分类?在 Google Analytics 官方的帮助文件,也给出了另外一个应用案例

       值得注意的是,原来在设置 _setVar() 函数的时候,整个网站的跳出率会出现重大的偏差,不过在最近的google analytics官方博客,指出该bug已经修正,客户在进行这方面设置的时候,还是要注意对比前后数据是否有重大偏差。

通过 _trackPageview 区分不同类型的评论

豆瓣上的书评,影评和乐评可以说是豆瓣网站的核心价值所在。一般评论的URL格式如下:

豆瓣上单条评论的URL

当我们查看该页面的网页源代码时,会发现有趣的现象:

豆瓣单条评论页的 Google Analytics 代码

      我们知道,一般 Google Analytics 的_trackPageview() 括弧中的参数是留空的, Google Analytics 会自动捕获网址的 URL 参数,如果在 _trackPageview()括弧中输入特定的数值,那么在 Google Analytics 的报表中,URL 将是我们指定的参数,而不再是我们在地址栏看到的 URL。

      如上面的例子,我们在 Google Analytics 中看到的URL将是/book/review/1946018/,而不再是我们在浏览器地址栏看到的/review/1946018/

      当所在频道是电影或者音乐时,_trackPageview() 中的参数将根据所在频道的属性,变为/movie/xxxxx 或者 /music/xxxxx的数值。

      豆瓣通过对的参数进行重新指定,主要有以下的好处:

        保证了用户和搜索引擎看到的 URL 比较简短,达到 URL 对用户友好和对搜索引擎友好的目的;而在 Google Analytics 报告中,通过 内容/内容细目/ 报告,又能了解到各个频道总的浏览情况。

      在GA的内容细目报告中,将会多出 /book/ /music/ /movie/ 这样的文件夹来,总而获得各个频道的合计浏览数据。

      而如果只是使用默认 _trackPageview(),你将只能得到所有评论页面的浏览数据,而无法得到细分的各个频道的浏览数据。

关于_trackPageview()的具体的使用方法可参照 Google Code 的说明

      注意事项:使用 _trackPageview() 参数重新指定 URL 之后,网站覆盖图的数据将受到影响。可参阅 Google Analytics 的官方帮助文件

      除了豆瓣使用 _trackPageview() 来对URL进行重写,大众点评网也采用了类似的做法(应该是比豆瓣更早采用。。。因为是我在点评网任职时候实验的做法;那时候豆瓣还没有使用 Google Analytis 统计代码,呵呵),有兴趣的同学可以自己去研究点评的 Google Analytis 代码。

原文: http://xiaolin0199.javaeye.com/blog/587390

分类: 其他 标签:

MySQLdb for Python使用指南/Python的数据库操作

2010年5月25日 没有评论

       注意一点就是进行数据ADU操作时,要conn.commit()进行提交,不然数据在数据库有过逗留,但并未最后对数据进行实质的ADU.

      可以从这里获得MySQLdb这个库http://sourceforge.net/projects/mysql-python
        如果你不确定你的python环境里有没有这个库,那就打开python shell,输入 import MySQLdb,如果返回错误信息,那就表示你的机器上没有,赶紧去下载一个.我的机器是win xp,所以我下载了win环境下的exe那个,直接双击完成安装.

在介绍具体的操作前,先花点时间来说说一个程序怎么和数据库进行交互
1.和数据库建立连接
2.执行sql语句,接收返回值
3.关闭数据库连接
使用MySQLdb也要遵循上面的几步.让我们一步步的进行.

0.引入MySQLdb库
import MySQLdb

1.和数据库建立连接
conn=MySQLdb.connect(host="localhost",user="root",passwd="sa",db="mytable")
提供的connect方法用来和数据库建立连接,接收数个参数,返回连接对象.

比较常用的参数包括
host:数据库主机名.默认是用本地主机.
user:数据库登陆名.默认是当前用户.
passwd:数据库登陆的秘密.默认为空.
db:要使用的数据库名.没有默认值.
port:MySQL服务使用的TCP端口.默认是3306.
更多关于参数的信息可以查这里
http://mysql-python.sourceforge.net/MySQLdb.html

然后,这个连接对象也提供了对事务操作的支持,标准的方法
commit() 提交
rollback() 回滚

2.执行sql语句和接收返回值
cursor=conn.cursor()
n=cursor.execute(sql,param)
首先,我们用使用连接对象获得一个cursor对象,接下来,我们会使用cursor提供的方法来进行工作.这些方法包括两大类:1.执行命令,2.接收返回值

cursor用来执行命令的方法:
callproc(self, procname, args):用来执行存储过程,接收的参数为存储过程名和参数列表,返回值为受影响的行数
execute(self, query, args):执行单条sql语句,接收的参数为sql语句本身和使用的参数列表,返回值为受影响的行数
executemany(self, query, args):执行单挑sql语句,但是重复执行参数列表里的参数,返回值为受影响的行数
nextset(self):移动到下一个结果集

cursor用来接收返回值的方法:
fetchall(self):接收全部的返回结果行.
fetchmany(self, size=None):接收size条返回结果行.如果size的值大于返回的结果行的数量,则会返回cursor.arraysize条数据.
fetchone(self):返回一条结果行.
scroll(self, value, mode=’relative’):移动指针到某一行.如果mode=’relative’,则表示从当前所在行移动value条,如果 mode=’absolute’,则表示从结果集的第一行移动value条.

下面的代码是一个完整的例子.
#使用sql语句,这里要接收的参数都用%s占位符.要注意的是,无论你要插入的数据是什么类型,占位符永远都要用%s
sql="insert into cdinfo values(%s,%s,%s,%s,%s)"
#param应该为tuple或者list
param=(title,singer,imgurl,url,alpha)
#执行,如果成功,n的值为1
n=cursor.execute(sql,param)

#再来执行一个查询的操作
cursor.execute("select * from cdinfo")
#我们使用了fetchall这个方法.这样,cds里保存的将会是查询返回的全部结果.每条结果都是一个tuple类型的数据,这些tuple组成了一个tuple
cds=cursor.fetchall()
#因为是tuple,所以可以这样使用结果集
print cds[0][3]
#或者直接显示出来,看看结果集的真实样子
print cds

#如果需要批量的插入数据,就这样做
sql="insert into cdinfo values(0,%s,%s,%s,%s,%s)"
#每个值的集合为一个tuple,整个参数集组成一个tuple,或者list
param=((title,singer,imgurl,url,alpha),(title2,singer2,imgurl2,url2,alpha2))
#使用executemany方法来批量的插入数据.这真是一个很酷的方法!
n=cursor.executemany(sql,param)

需要注意的是(或者说是我感到奇怪的是),在执行完插入或删除或修改操作后,需要调用一下conn.commit()方法进行提交.这样,数据才会真正保 存在数据库中.我不清楚是否是我的mysql设置问题,总之,今天我在一开始使用的时候,如果不用commit,那数据就不会保留在数据库中,但是,数据 确实在数据库呆过.因为自动编号进行了累积,而且返回的受影响的行数并不为0.

3.关闭数据库连接
需要分别的关闭指针对象和连接对象.他们有名字相同的方法
cursor.close()
conn.close()

三步完成,基本的数据库操作就是这样了.下面是两个有用的连接
MySQLdb用户指南: http://mysql-python.sourceforge.net/MySQLdb.html
MySQLdb文档: http://mysql-python.sourceforge.net/MySQLdb-1.2.2/public/MySQLdb-module.html

引用: http://xiaolin0199.javaeye.com/blog/585574

分类: 其他 标签:

PHP和Python/Ruby的运行机制的本质区别

2010年5月24日 没有评论

       刚接触CakePHP是刚进公司的时候,刚进来接手公司项目,也是第一次接触CakePHP,开始感觉"很过隐",也确实感受到了Rails的力量,但随着对项目的深入研究,质疑也开始越来越强烈,CakePHP的诟病也越来越明显。也确实一个稍大一点的项目如果用一个通用框架的话难免会出现顾此失彼的问题,前段时间接触了另外一个框架DooPHP,感觉这个框架的设计理念有很多可以借签的地方。因为这段时间精力有限,想尽快把Python拿下来,等有时间了再去写些DooPHP的东西吧。

      PHP和Python/Ruby的运行机制有一个本质区别:PHP是每次HTTP请求过来以后,初始化全部资源(例如创建数据库链接、加载系统类库,创建缓存等等),处理完毕,释放全部资源,这不像Python/Ruby之类带有GC的脚本语言,Python/Ruby是初次启动的时候初始化资源,随后的请求就不必再次初始化资源了。

这种机制的差异带来的区别就是:

1、PHP极难出现严重的内存泄露问题,随便你代码写的多烂,反正每个请求一执行完毕,所有资源统统释放光。而Python/Ruby则需要依赖GC来回收内存,因此稍有不慎,还是会出现GC无法释放的内存泄露问题。

2、PHP每次请求都要初始化资源,这个开销非常大。所以尽管PHP解析器本身的运行速度是极快的,但是一旦使用复杂的PHP框架,那么由于需要每次请求的时候初始化整个框架,性能的下降非常厉害,你用一个很复杂的PHP框架的结果就是整体性能被Ruby远远甩开。这也是为什么PHP社区这么多年来,并不怎么倾向于使用框架的原因之一。

3、由于PHP这种每请求初始化资源的机制,也造成了PHP添加跨请求的高级特性相当困难,这是PHP本身一个很大的限制,但是反过来说,正是这种限制使得PHP始终保持在一个比较简单的web语言上面,而正是这一点才是PHP得以成为互联网第一Web编程语言的原因,因此也未必就不好。

总之,PHP和Ruby的差异还是很大的,不适合放在一起比较,其实应该比较的是Ruby和Python才对。

      所以我觉得Rails这种框架性做法被PHP跟风以后,其实是把PHP带上了邪路,所以不如说是Rails在误导PHP的发展。顺便多说一句:DHH在编写basecamp之前,一直是用PHP的,并且自己还写了一个PHP的快速开发框架,他改用ruby以后,把当初自己写的PHP框架也移植过来了,这个框架实际上是Rails最初的原型。那么为什么DHH当初不直接基于PHP做Rails呢?非要改用ruby以后,才发表rails呢?你看看PHP这种运行机制就知道了,PHP做复杂的web开发框架并不是一条光明的道路。

引用参考:http://hanssonlan.javaeye.com/blog/403496

分类: 其他 标签:

XA™的日记 豆瓣的架构

2010年5月20日 没有评论

        豆瓣是一个值得让人敬佩的网站,国内为数不多的大型网站中,就技术创新和分享来讲,豆瓣做的很不错,我一直比较关注豆瓣.这是一篇言谈手记类文章,豆瓣是一个Python写的WEB2.0网站,很多关于Python以及网站架构方面的知识值得见识,对于新手,Python来说.

关键字包括:nginx,lighttpd,quixote,Memcached,mogile FS,Mako,Gentoo Linux,Xapian,spread

ps:窃以为第一段关于语言的采访,相当[csdn]化

      你要是愿意,就买一枝三块钱的玫瑰,送给我吧,这城市也是怪让人伤心的,我想死心塌地的爱上你”

     这是一个叫钟童茜的歌手的歌,我在豆瓣网站发现有人评论,才知道了这首有些凄凉的歌曲。你几乎不可能从百度的最流行的mp3的列表中找到它,因为它不是那么有名,也许是这个原因,引发了我采访豆瓣的愿望。接受我采访的是,豆瓣网站的技术总监洪强宁先生和产品经理张贝宁女士。

本刊记者:好,现在开始,豆瓣是一个非常著名的Web2.0网站,你们的开发语言选择的是Python,我想问的是,为什么选择Python?

洪强宁:我们选择Python的理由是它是动态语言,具有动态语言的优点,比如开发特别迅速。我们做的是一个Web2.0的网站,这种网站的特点就是always beta,用户的需求在随时发生变化,我们也不断发现新的价值。所以网站的结构和程序会不断变化,如果用Java做,你的开发量比较大,你就难以做出迅速地改变。Python的特点就是开发迅速,你可以在一两个小时,就做出一个功能。或者说已??上线了,用户反映需要某一功能,也可以比较快地做出来。

本刊记者:这就是TDD,敏捷开发的思路,和传统的方式有些不同。但是会有另一方面的问题,Python的程序员好找吗?在国内会Python的要比会Java程序员少的多。

洪强宁:对,确实是。在中国用Python的人确实不多,也给我们寻找开发任何人员带来困难。不过从另一方面说,也有好处,因为没有一个学校去教Python,会Python的人都是自己学的,也就是说他知道自己需要什么技术,而且能够通过自学掌握它,包括Python的资料中文比较少,需要学习者接触第一手资料,这都使得Python程序员的平均水平,要比使用其他热门语言的平均水平要高。另一方面Python也越来越流行,在国外比较流行的动态语言有Perl,和Python,现在Python已经超过了Perl。

本刊记者:不过,在Web开发这方面有许多选择,比如,Java,.NET,和PHP,在这个格局里Python还是比较弱势。

洪强宁:对,当然,它是新兴语言。在未来,我相信,至少在在Web2.0网站开发方面,它会有自己的一个位置。

本刊记者:还有问一个问题,Python与Perl比较怎么样?因为Python的面向对象的特性好一些,代码看起来更容易理解一些吧,我以前是用 Perl写程序的,觉得Perl的程序代码看起来比较乱。

洪强宁:对,Perl 是write once风格的,一个人写完了,过一段时间,可能自己都不能看懂,它确实很强大,但比较适合当作个人工具使用,不太适合团队的开发。Python的哲学是解决问题的最好方式只有一种,这样同样的功能,每个人写出来的程序样子应该差不太多,比较易于理解,更适合团队开发。

本刊记者:还有一个问题,,有一种说法,认为Python比较慢,在性能方面会不会有问题?

洪强宁:这个问题可以分两个方面说,首先,说Python慢,这是和编译语言比,比如与C,C++,Java比,在动态语言中,它并不慢,它比Ruby要快,它和Perl性能相当。如果选择动态语言的话,Python并不是很慢。另一方面,如果做网站开发,语言的不是速度的瓶颈,比如我把我们现在用Python写的程序全部用C写,程序当然会快一点,但是改变不是很大。Web网站一般会有很多对IO的操作,比如对数据库的访问,对硬盘的访问响应用户的请求,80%,90%你的时间都花在IO上,语言的速度,相对而言,不是那么重要。也可以这样说,网站的性能主要取决于架构设计的是否合理。因为网站需要响应大量的并发的请求,如果你的设计的不好,即使你用C写的,也可能无法应付。所以更多的考虑是在架构设计上,要使架构体系不会产生速度瓶颈。

本刊记者:那您能简要地介绍一下豆瓣的架构吗?

洪强宁:关于豆瓣的系统架构图,首先我们在Web server上做个划分,把网站内容分为动态内容和静态内容。在豆瓣上所有的html都是动态内容,图片都是静态内容。分成两个Web 服务可以做不同的调优。 对动态内容,我们用的是nginx和lighttpd的混合,nginx做负载的平衡,lighttpd通过 SCGi 与application server相连,application server是基于 quixote这个框架写的。

application server拿到用户的请求,分析用户的url,并且利用外部的资源,比如数据库,组合成一个html,返回。从数据库存取会比较慢,数据库有大量的IO,我们使用cache,我们使用的是Memcached,这是一个分布式的内存的cache,比如你可以用很多机器,每个机器有两个G的内存,我们自己开发了client端来使用它,另外如果用户有搜索请求,我们会用搜索引擎。Xapian是一个C++写的开源的搜索引擎,我们通过Web service去访问它。其他,我们还提供了另外的Web service接口响应用户的请求,比如要访问某个文件。spread是我们最近加了一部分,用户有的请求可以采用这样的异步服务。

数据库是这样的,两个MySQL做成一对,一个master ,一个 slave,根据应用划分,使得load不会太高。这个图上??的是两对,实际上有三对。还有一个slave,一方面作为备份,一方面用作数据挖掘,因为不能对线上的数据做直接操作。

对于静态部分,我们也是用nginx,你注意到豆瓣现在有日记的贴图功能系统,用户可能上传很多图片,我们采用的方案是用了mogile FS ,这是一个分布式的文件系统,同时可以做备份,保持高可用性,可以提高很大的IO。

关于application server,它都是用Python写的。我们是用的MVC方式,Controller我们用的是quixote ,它接受用户的请求,根据这个URL去找到Model的某个具体的函数来执行,它是一个dispatcher,当中会判断用户的权限等。然后再传给View,View根据模版进行渲染,形成网页。View的模版,我们以前是用的是PTL,PTL很高效,最近引用了mako,这是一个比较现代的开源的模版,用它写出的代码比较好维护,比PTL好维护一些.。同时,在使用mako的同时,我们的工程师做了很多加速的工作,现在mako的代码有很多是豆瓣的人写的。

你如果注意过Python的Web开发框架的话,你会发现Python的有三个比较著名的框架,Django,Pylons,TurboGears,Pylons默认的模版就是Mako。

下面的就是Model,业务模块,核心是类是User,因为Web2.0是以人为本,我们肯定会有一个User。只有人也做不了事情,还要有物。豆瓣的物,就是Subject,比如书,比如评论,比如小组等。

与数据库进行链接,我们一个很轻量级的与数据库进行链接,这也是一个开源项目,SQL Farm Manager。这个Web service,豆瓣中有很多用的都是Web service。

本刊记者:好,还想问您一个问题,Web2.0会不会也在架构设计中也有所体现呢 ?

洪强宁: Web2.0用户的反复的操作非常多,你需要一个非常流畅的体现。这需要一些技术来实现,比如Ajax;豆瓣花了很多钱很多精力,来提高性能,比如买好的机器,使用Gentoo Linux,为什么使用Gentoo Linux,因为它方便调优。还有,大量的使用cache。在数据库调优方面,我们也花了很大的精力。

另一方面,Web 2,0是用户提供数据的,用户有很多写操作。这样很多1.0优化方法在2.0中行不通。豆瓣在数据库上用的是分库的方式。除此之外我们还尝试了一些其他的方法。

本刊记者:我现在想问张贝宁一个问题,您能否谈一下Web2.0社区网站和传统的社区网站的区别?比如天涯论坛,和豆瓣的区别。

张贝宁:先说一下Web 2.0 的概念,传统网站,用户到这些网站,只是看信息,这些信息是怎么来的呢,比如像Google,它是抓来的,或者像新浪这样的门户网站,是用户给你编好的。你到这样的网站,只是获取信息,你不能创造信息,也不能决定它放的位置。按照业界的理解,Web 2.0相对于Web 1.0,它是以用户为中心的,或者说是以用户创造内容为主,并且可以决定展现方式。你刚才说的传统的社区,在某种程度上,也可以说是2.0的,因为它也由用户提供内容。不过早期的BBS,网站以内容作分类,比如体育,军事,文学等。用户不能形成自己的分类。在豆瓣,用户可以对任何一个话题进行讨论,这完全是用户自主的。这还只是关系到豆瓣的小组的功能,如果拿天涯论坛和豆瓣做比较的话,豆瓣与天涯这样的BBS不同还在于,它首先有一个物的概念,比如书,音乐,和电影。

本刊记者:我也发现了这点。这样的组织方式,给人的感觉会非常不同。比如我们要查找对余华的小说《活着》的评论,在豆瓣就比较容易找到认真,有质量的评论。而在传统的BBS上,你只能用查找的方式,搜索“活着”这个词,找出的东西,也可能还不是谈论《活着》这本小说的,而只是其中的文本包含了“活着”这个词,而且有很多无意义的吵架帖。豆瓣的组织方式,让人感觉很严肃,雅气。不过,我也发现了一个或许有些不便的地方,比如,我要在讨论德里达的小组回帖,在一般的BBS可以匿名,或具有一个ID就行了,但在豆瓣,我要首先参加德里达这个小组。

张贝宁:对,是这样的。豆瓣更关心的是人群,就是对同一话题和事物有兴趣的人群,而不是帖子,这与传统的BBS确实有一些区别。

本刊记者:好,就到这里。谢谢你们两位能够接受我的采访,分享你们的经验与思想。

原文:http://www.douban.com/note/29557381/

分类: 其他 标签:

Django新手需要注意的10个要点

2010年5月20日 没有评论

      博猪很牛X,JavaEye很小气,想回个评都还要搞个什么测试,鬼地去,我推上见过JavaEye的人,感觉印象不好.

      接触django是从上个月开始,学习python时间也不长,但我经常在社区看看别人发表的文章,早上看到一篇不错的博客,却一直不能访问,最终从bing的缓存里找到,因为害怕丢失和忘掉,所以顺便翻译过来,放到这里,同时也分享给大家,贡献给各位django初学的朋友们,希望能有一些帮助:)

原文地址是:http://zeroandone.posterous.com/top-10-tips-to-a-new-django-developer

1,不要将项目名称包含在引用代码里

      比如你创建了一个名为"project"的项目,包含一个名为"app"的应用,那么如下代码是不好的:

Python代码 复制代码

from project.app.models import Author

      缺点在于:应用和项目变成了紧耦合,无法将应用轻易变得可重用。如果将来要换一个项目名称,那你可有得受了。

推荐的做法是:

Python代码 复制代码

from app.models import Author

请注意,你需要将项目的路径配置在PYTHONPATH中。

2,不要硬编码MEDIA_ROOT和TEMPLATE_DIRS

项目配置文件settings.py中不要使用如下代码:

Python代码 复制代码
  1. TEMPLATE_DIRS = ( "/home/html/project/templates",)   
  2. MEDIA_ROOT = "/home/html/project/appmedia/"

当你在部署到生产环境,或者迁移服务器的时候,就会发生问题。

推荐使用如下方式:

Python代码 复制代码

SITE_ROOT = os.path.realpath(os.path.dirname(__file__))   
MEDIA_ROOT = os.path.join(SITE_ROOT, ‘appmedia’)   
TEMPLATE_DIRS = ( os.path.join(SITE_ROOT, ‘templates’),)  

(也可以使用abspath,跟realpath的区别请参考http://rob.cogit8.org/blog/2009/May/05/django-and-relativity-updated/

3,不要将静态文件的路径硬编码在模板中

模板中链接CSS,javascript或图片的时候,不建议使用如下方式:

Html代码 复制代码

<link rel="stylesheet" type="text/css" href="/appmedia/amazing.css" />  
<script type="text/javascript" src="/appmedia/jquery.min.js"></script>  

      当你的项目需要将静态文件用其他服务器提供的时候,通常会是另外一个http地址,那么你就得把所有的/appmedia/替换成新的地址,做网站写代码已经够乏味的了。

没有后顾之忧的解决方法是使用{{ MEDIA_URL }}代替硬编码的路径:

Html代码 复制代码

<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}amazing.css" />  
<script type="text/javascript" src="{{ MEDIA_URL }}jquery.min.js"></script>

模板上下文变量怎么获取到呢?请使用RequestContext即可:

Python代码 复制代码

return render_to_response("app/template.html", {‘var’: ‘foo’},   
context_instance=RequestContext(request))

从RequestContext里还可以获取到当前用户等信息,更详细的介绍请参考:
http://www.b-list.org/weblog/2006/jun/14/django-tips-template-context-processors/

4,不要将业务逻辑代码写到视图里

       不要迷惑,虽然你可能看过很多书和例子,它们把逻辑都写在了views.py里,但请你别这么做。因为这样不利于单元测试,不利于重用代码。

      那我的业务逻辑应该放哪里呢?推荐放到模型里或者单独建立一个辅助(helper)模块。

当然,从模型得到一个Author,获取Author列表的代码是可以放到视图里面的。

5,部署时别忘记将DEBUG设置成False

我们常常忘记在部署时禁用DEBUG,有很多种方法自动来处理这个配置:

Python代码 复制代码

import socket     
if socket.gethostname() == ‘productionserver.com’:   
    DEBUG = False  
else:   
    DEBUG = True   

此方法请参考:http://nicksergeant.com/blog/django/automatically-setting-debug-your-django-app-based-server-hostname

另一种途径是使用不同的配置文件:

Python代码 复制代码

#文件名:settings_debuy.py   
#包含调试模式的配置信息   
#使用python manage.py runserver settings=settings_debug.py来运行项目      
from settings import *      
DEBUG = True    
#还可以配置更多在调试时使用的变量:)  

此方法请参考:http://blog.dpeepul.com/2009/07/02/from-now-you-will-never-forget-to-put-debug-true-in-django-production-environment/

6,只加载一次自定义的模板标签

当需要使用自定义或者第三方的模板标签和模板过滤器时,通常要在模板中使用:

Python代码 复制代码
{% load template_tags %}

实际情况是,需要在所有用到自定义模板标签和模板过滤器的模板中都使用上面的代码,这样就不DRY了。

Python代码 复制代码

from django import template     
template.add_to_builtins(‘app.templatetags.custom_tag_module’)  

请将以上代码放到项目启动时能加载的模块中(settings.py, urls.py, models.py等)即可。

上面代码的作用是在项目启动时就把自定义模板标签或过滤器加载进来,模板中任何一个地方都可以使用它们,而不需要{% load template_tags %}。

7,合理配置和使用URL

不要将URL全都配置在一个urls.py文件中,比如:

Python代码 复制代码

urlpatterns = patterns(,   
  url(r‘^askalumini/question/$’,‘…..registerInstitution’,name=‘iregister’),   
  url(r‘^askalumin/answer/$’,‘someview…..’,name=‘newmemberurl’),   
  url(r‘^institution/member/$’,‘someview…..’,name="dashboardurl"),   
  url(r‘^institution/faculty/$’,‘editInstitute’,name="editinstituteurl"),   
url(r‘^memeber/editprofile/$’,‘editProfile’,name="editprofileurl"),   
  url(r‘^member/changepassword/$’,‘changePassword’,name="changepasswordurl"),   
  url(r‘^member/forgotpassword/$’,‘forgotPassword’,name="forgotpasswordurl"),   
  url(r‘^member/changepicture/$’,‘changePicture’,name="changepictureurl"),   
  url(r‘^member/logout/$’,‘memeberlogout’,name="logouturl"), ,   
)  

建议的方式是将各应用的URL配置在各自的urls.py中,这样可以使应用更容易重复使用到不同项目里:

Python代码 复制代码
  1. urlpatterns = patterns(,   
  2.   (r‘^$’, include(‘institution.urls’)),   
  3.   (r‘^institution/’, include(‘institution.urls’)),   
  4.   (r‘^askalumini/’, include(‘askalumini.urls’)),   
  5.   (r‘^member/’, include(‘member.urls’)),   
  6. )  

如下是应用askalumini的urls.py:

Python代码 复制代码
  1. urlpatterns = patterns(‘askalumini.views’,   
  2.   url(r‘^$’,‘askHome’,name=‘askaluminiurl’),   
  3.   url(r‘^questions/(?P<questionno>\d+)/$’,‘displayQuestion’,name=‘askquestiondisplay’),   
  4.   url(r‘^askquestions/$’,‘askQuestion’,name=‘askquestionurl’),   
  5.   url(r‘^postcomment/$’,‘postComment’,name="askquestioncomment")   
  6. )  

      刚才提到静态文件路径不要硬编码,url的处理方式也尽量不要硬编码,否则当你更改一个地址时会牵涉到多处的修改,可以使用一些url函数来处理。

在/project/askalumini/urls.py中,为每一个url定义了name,它可以帮助我们有效地在视图、模板和模型中处理url,而不是硬编码。

为保证名称的唯一,请遵照将url命名为<appname>/<somelabel>的习惯用法。

举例来说,在views.py文件中有如下代码:

Python代码 复制代码
  1. HttpResponseRedirect("/askalumini/questions/54")  

请改为:

Python代码 复制代码
  1. from django.core.urlresolvers import reverse   
  2. HttpResponseRedirect(reverse(‘askquestiondisplay’,kwargs={‘questionno’:q.id}))   

在模型中使用models.permalink装饰器来格式url:

Python代码 复制代码
  1. @models.permalink   
  2. def get_absolute_url(self):   
  3.     return (‘profileurl2’,(),{‘userid’: self.user.id})  

在模板中使用url标签代替硬编码:

Html代码 复制代码
  1. {% url askquestiondisplay 345 %}   
  2. <a href="{% url askquestiondisplay 345 %}"> Ask Question </a>   

8,调试

调试通常会借助一些第三方工具来获得更多的运行时信息。

一个请求执行了多少句SQL?花了多长时间?

调用的哪个模板?客户端设置了什么COOKIE?SESSION呢?。。。

你可以使用django-debug-toolbar查看上面甚至更多的信息:http://github.com/robhudson/django-debug-toolbar

另一个工具是Werkzeug debugger,它可以在错误页面打开python shell,让你更方便的跟踪错误信息,请访问:http://blog.dpeepul.com/2009/07/14/python-shell-right-on-the-django-error-page/ 获得更多信息。

还有pdb,一个强大的调试工具:http://ericholscher.com/blog/2008/aug/31/using-pdb-python-debugger-django-debugging-series-/

9,了解pinax备用

django最大的优点是代码重用,DRY,pinax就是这样一个平台,包含了许多可拿来直接使用的代码,比如openid,电子邮件验证等等。请访问:http://pinaxproject.com/

10,了解一些著名的第三方应用

1)数据库升级工具

什么是数据库升级工具?你运行了syncdb,运行了一年之后,对模型做了更改,添加了字段,删除了字段,要再运行syncdb吗?或者ALTER TABLE …?

django-evolutions可以帮你完成上面的事情,但它好像不够强壮:http://code.google.com/p/django-evolution/

South能很强壮地完成上面的事情,但是需要学学怎么用:http://south.aeracode.org/

2)模板系统

django自带的模板系统是可以替换的,并且各自有优缺点。

template-utils增强了模板的比较标签等功能 ,并提供其他的一些实用特性:http://django-template-utils.googlecode.com/svn/trunk/docs/

Jinja是一个完整的第三方模板系统,可以替换默认模板系统,它提供了许多优越的特性:http://jinja.pocoo.org/2/

3)第三方应用

django command extensions提供了很多实用的命令行功能:

shell_plus加载所有django模型

runserver_plus整合了Werkzeug调试工具

生成模型图表,你可以展示给你的老板

……

请参考:http://ericholscher.com/blog/2008/sep/12/screencast-django-command-extensions/

Sorl可以生成缩略图:http://code.google.com/p/sorl-thumbnail/

…………

—END—

另外,从原文的评论里也有不少发现:

原文:http://shinyzhu.javaeye.com/blog/593427

分类: 其他 标签: