- 浏览: 632988 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
liuche20083736:
非常好
从问题看本质: 研究TCP close_wait的内幕 -
xiaopohai85707:
优化算法与原来需求不符
过滤字符的性能调优?挤一挤还是有的 -
kmy_白衣:
生成的area图有时候 标签的数值和图标上看上去的数值不一致。 ...
OpenFlashChart2之恶心文档 -
tom&jerry:
大神,请教一个问题,按名称排序为何无效,用的2.4.3 XPA ...
深入浅出jackrabbit之十三 查询之AST和QT -
jd2bs:
改成精确匹配可以了< filter-mapping &g ...
细谈Ehcache页面缓存的使用
[size=medium]这几天花了点时间看了一下python世界中的django,正如某大所说,掌握另外一门语言是有必要的,同样我也作出了自己的选择。从这几天的学习中,我确实也发现其他语言及其框架等确实有一种与众不同的感觉。下面我把自己这几天看到的东西稍微作了一下总结,本文并不是django的教程,而是ahuaxuan对django的一些自己的理解,可能有些不成熟的地方,希望大家不要吝惜手中的砖头。
一 django的orm
如果有人问我最喜欢django什么,我会耗不犹豫的告诉你是django的orm,这个想法的产生完全来自于我长时间来积累的对hibernate的“不满”,虽然从理智的角度来看,hibernate做的是非常的正确的,因为它并不是只针对互连网而产生的,它的主要市场应该还是在企业应用上,不过把它用在互联网并非不可以,只不过大家更多的时候会选择ibatis之类,因为不知道hibernate的人总是会说hibernate没有ibatis快(其实我最烦这个,片面的比较是没有意义的)。正是hibernate的目标是打造成java界一个全方位,全能的orm框架,所以的它学习曲线和使用的复杂度日益的提升,要完全掌握好hibernate不是一件容易的事情(不要告诉我你会点crud,知道点lazy load你就掌握好hibernate了),再回头来看django的orm,如果说要把hibernate说清楚需要800页的书,那么要把django的orm说清楚,200页就够了(事实上它的官方文档只有十几页的样子)。下面我举一个我正在做的例子,这里有一个自关联的对象(事实上django的orm是基于model,这点和ror不太一样,有人跟我讲过ror是数据库驱动),这个对象有一个父对象,通常我们的菜单会定义成这样的对象,这样的菜单可以无限级向下扩展:
Category中又定义的Admin是为django的Admin模块服务的。
瞧,我们定义的域模型只需要这些代码就够了,models.Model是父对象,所有的model对象都需要继承这个对象,这个对象提供了很多常用的数据库方法,不过不是基于sql的,还是基于对象的,如同Criteria一样。下面列出常用的一些查询Category的方法。
1,
查询category by id(从页面上传过来的)
2
3
4
5 复杂的查询可以使用extra方法,例如:
当然django的orm提供了很多很常用的功能,这里不一一举例了,注意,这里我说的是提供了很多很常用的功能,至于hibenate中比较复杂的映射策略,在django中我并没有看到。但是我反而高兴我没有在django中找到这个功能,因为django本身的定位是快速的互连网开发,它不需要太多的关注这个领域很少出现的东西,这样带来的优点是学习曲线的降低和开发效率的提高。
二 django的模板
Django的模板可以说是非常的简洁,简洁到我不知道说什么好,简洁到看一下文档就能上手使用,在java中,freemarker和velocity我都用过,最复杂功能最强大的还是freemarker,支持jsp tag的嵌入让我们可以重用很多已经存在的组件,这一点我在之前的文章中也有过比较详细的描述(强强联手,看freemarker和displaytag的结合),由于了解,才有发言权,django的模板可以说是为互连网应用而诞生的,简洁及快速开发的特点让人情不自禁的喜欢。大多数模板语言的基本语法都是类似的,比如在freemarker中显示值是${},而在django是{{}},freemarker中if判断为<#if></#if>,而django中是
再看看在django中渲染模板的方法,有两种:
第一种
第二种
render_to_response相当于封装了loader.get_template方法而已,所有的一切看上去都是那么的简单,模板无处不在,今天你模板了吗?
插一句题外话,关于jsp的题外话,不管是ruby,还是c++,还是python,在它们的web框架中都使用了模板,java中也有很多模板,我们最熟悉的是freemarker和velocity。这从一个侧面反映出我们web开发中的一个模式,那就是我们的view基本上是基于模板产生的,而jsp这个东西应该来说是时代的产物,在那个混乱的落后的时代产生的,不过很奇怪的是现在还有这么多人抱着它不放。
三 django的form
Django有两种form,一种是自己定义form class,还有一种是通过我们定义的model自动form class。
由于ahuaxuan只做 了一个信息发布的小例子,所以并不能全面的了解或者理解django中form的所有细节,不过从我涉及到的部分来讲,我对django的从模型创建表单的做法确实感到有比较大的局限性,因为很多时候,model中的数据 并不是从页面上来的,在这种情况下,form对象被构造出来之后,ahuaxuan还没有找到修改form中值的方法。
而自定义form类也比较麻烦,就是要写自己的model,这个和我们之前的做法比较不一样,这里的form代表我们java中的value object,model是domain object,在我们的ssh框架中我们通常把value object继承我们的domain object。虽然一堆又一堆的人提出了反对意见,说要把这两个对象分开,因为他们处在不同的层次中,但是从实践经验中,我们可以看到,这样做没有什么不好。而在django中自定义form和model分开的行为可能比较符合一些人的心理。
不过自定义forms也有比较让人称道的地方,在form中我们可以自定义验证规则,同时我们可以根据form对象直接生成页面中的内容,不过这一点其实也有比较麻烦的地方,就是如果要改变样式的时候就比较麻烦。不过总的来说django的form还是比较有特点的,而且一定程度上给我们带来了方便。
四 django的url转发
Django的url转发是基于正则表达式的,有的人叫好,有的人叫差,我就是叫差的那一拨人之一。url转发应该是一个非常清楚,非常明亮的事情,可是用上这个正则表达式匹配的东西之后,我郁闷了,所以我只能回到遥远的过去去绕过这个东东,我不用总可以了吧。
从目前目前掌握的知识来看,django的views里的东西其实是controller,为什么叫views?不得而知,不过一直这么沿用下来了,即使是在自然界,很多表面上去不太一样得东西,其实内部的原理是一样的,我就觉得django的views就是struts1.x中的action,为什么这样说呢,让我们来看看两段比较的代码,第一段是django的,第二段是struts1.x的:
――――――――――分隔线―――――――――――――――
从形式上来看,两者出奇的相似,比如说传入的参数等。我们知道python是面向对象的语言,但是事实上它也支持函数编程,如果def定义在class内部,那么就是对象的方法,否则,就可以认为是函数编程了,看看,我们的views里的东西都是函数,views其实是一个模块,这个模块我们可以认为是struts1.x中的action,而views中的函数可以认为是action中的方法。它们是远房亲戚。
那么说到这里,曲线救国的线也找到了,就是struts.1x中DispatchAction,我们只要在url后面追加一个methodName就可以指定我们要调用views中的哪个函数了。代码如下:
这个execute方法成为了所有的方法的入口(我们在urls.py中只需要这样定义:
接着在execute方法中判断methodName的值,然后根据这个值找到对应的函数,再调用它,getattr类似于java中的反射,可以让我们动态调用任何我们想调用的函数(只要我们知道函数名的话)
这样我们在urls.py中只需要定义很少的值(有几个模块就定义几行就够了)就可以完成我们的项目了,以后维护起来也没有这么麻烦和复杂。
一个小小的缺憾是没有自带restful,不过听说有一个插件可以支持。
六 admin
Django的admin功能号称是django的杀手级特性(killer feature),这一说可以说是恰如其分,毫不夸张的,从我做的这个例子来看,当我做网站的时候,基本上只需要关注前台页面的展示这部分,后台的功能基本上都自动有了,比如我做的例子是一个二手信息发布平台,category是二手信息的类型,还有一个information类,和category是多对一的关系,那么在后台,category和information的crud就自动生产了,由于category本身是一个自关联,所以在admin中 add category的时候,admin会根据我model的定义,自动要求选择一个parentCategory,而在add information的页面上,admin会要求我选择一个category来完成对一个information的创建,而以前在java中,这些工作都需要自己完成,当然也有很多工具可以自动生产crud,不过这些开源的工具基本上都是针对单个model的,而且生成的代码需要很大修改才能真正的把功能跑起来,最重要的一点是不能自动生成关联关系的管理。当然我也见过有公司做了基于数据库驱动的代码生产器,能生成完整可用的代码和页面,也包括关联关系的处理,不过由于语言特性的区别,在开发的时候我们还是要不停的重启server才能显示出效果来,虽然在技术上,为ssh实现这个功能并不难,但是会消耗不少时间在上面,消耗了很多时间的话,很少就有公司将其贡献出来了。所以个人认为django在这个功能上做得还是非常不错的,尤其这个功能可以节省开发者很多的时间。甚至有些时候,项目可以双线执行,用户通过admin输入数据,程序员开发前台,这样,前台功能做完之后,数据也有了,基本可以测试上线了。在需要快速开发的小项目上,这个特性显得尤其重要,因为django产生得时候就是基于这个场景。
当然有时候后台也没有这么简单,不过还好,admin提供了扩展的功能,我们可以自己写扩展的代码,然后集成到admin中去,不过事实上除了能改变admin的模板,我们不能改变任何admin的代码,不过我时常在想,如果admin支持代码自动生成的功能,那岂不是很美妙,我们可以随意的修改后台的功能了,否则我们就需要自己写代码,不如在生成的代码上扩展方便。
要使用admin,必须打开django的权限模块,这里简单介绍一下权限模块,django自带了一个权限模块,这个权限模块中的model对于熟悉权限这块的人来说再熟悉不过了,user,group,permission,user和group多对多,group和permission多对多,在acegi中,我们通常这样定义,user,role,resource,这个和django中的权限是一样的,不过在django中默认的permission的粒度是非常的粗了,是基于model的,如果我们要更细的权限模块,那么就需要自己扩展了。
总的来说admin给我的惊喜大于失望,虽然有点小小的不满意,但是总体来说还是非常赞的
五 部署
在这部分开始之前我也想聊聊之前我们一直在讲,而且将来还一直会讲下去的一个话题――状态。
之前我们一直在讨论,把用户的状态保存在一个集中的地方,尤其是大规模集群部署的情况下,同样,对于django来说亦是如此,可以说这条金科玉律不只是针对某种针对某个语言,某个框架,它应该是更高层次的一种理念。那么我们可以把状态放到什么地方呢,目前一些流行的选择是DB(内存表,或实体表),memcached,或者cookie,但这几种选择并不是可以随便互换的,比如业务数据较多的情况下,放在cookie中不是很合适,因为有可能超出cookie大小的限制,那么放在memcached中,很遗憾,memcached(使用slab的情况下)中也有它自己的限制,如果状态数据大小跨度较大,那么丢数据的情况有可能发生,ahuaxuan很久之前在测试环境下就碰到过这种情况,由于线上memcached开得较大,所以没有出现这种情况,关于这种事件发生得内部原因在ahuaxuan的另外一篇文章中已经有了非常详细的描述。那么放在DB上呢,显然,DB的压力也是我们需要考虑的问题之一。当然除了这些主流的选择之外,我们其他选择还有很多,比如memcachedb,或者timesten,或者其他等等,但是对于状态这种东西,尤其状态数据比较重要的情况下,我们一定要深入研究并理解状态数据的存储技术,否则可能会遇到我们异想不到的情况,比如很久之前我想破头也不会想到memcached是LRU是针对某个slab的(而且我还要插一句,LRU的时候其实并不是遍历slab中的chunk链表,而且只遍历最开始的50个数据而已,这样做纯粹是为了速度)。
目前对django来说基本上有两种部署策略,
第一种是利用mod_python将django运行在apache进程中,还有一种是webserver+fastcgi,这两种方式各有优缺点,在mod_python模式中,我们的webserver必须使用apache,apache在webserver这一领域已经独占鳌头很多年了,市场占有率也是远远的超过其他的webserver,不过近几年来,又崛起了几个其他的webserver,其中比较出名的是ligttpd和nginx,它们都以高性能和低内存消耗对apache发出了挑战,而mod_python是apache的插件,使用这种方式就把我们的webserver限定在apache上了,不过还好apache+mod_python也是非常的稳定的方案了。
第二种就是webserver+fastcgi,这里的webserver就可以随意选择了,大多数的webserver对提供了对fastcgi的支持,比如我们耳熟能详的lighttpd和nginx,而且据称在很多情况下,FastCGI能够提供比mod_python更为优越的安全性和效能。针对小型站点,相对于Apache来说FastCGI更为轻量级。据称qq的个人空间就是c++加fastcgi实现的,哦,这样做的优势在哪里呢,c++的处理速度将会非常的快,也就是说每个fastcgi处理一个请求将会非常快速,比如使用python需要50毫秒,c++处理这个请求有可能只需要20毫秒(这个例子未必准确,只是为了说明fastcgi的特性),虽然在开发上c++比较麻烦一点,不过在性能上,c++肯定是no1了,从这个例子上我们可以看到,使用fastcgi速度取决于处理一次请求的速度(废话,哪个不是这样)。
我们来看一下使用fastcgi的一般模式:1、WEB服务器收到客户端的页面请求 2、WEB服务器将这个页面请求委派给一个FastCGI 外部进程(WEB服务器于FastCGI之间是通过socket来连接通讯的) 3、FastCGI外部进程得到WEB服务器委派过来的页面请求信息后进行处理,并且将处理结果(动态页面内容)返回给WEB服务器 4、Web服务器将FastCGI返回回来的结果再转送给客户端浏览器。
对我们来说第3步是我们最需要关注的,因为第3步的速度严重影响着整个性能。由于fastcgi是基于进程的,所以,我们要根据我们的应用来开启数量合适的fastcgi进程,多开了是对资源的浪费,少开了就影响性能,这个类似我们在tomcat中开启处理请求的thread一样,只不过tomcat中的request handler thread在配置起来显然更加方便,因为我们只要关注线程池中最大的可以容纳的线程数,最大空闲线程数等就行了。
当然fastcgi对ahuaxuan这类刚刚跨出java世界的人来说有些不爽的地方,因为基于进程的东东共享数据比较麻烦,比如写一个ip查询的组件,功能是这样的,把ip地址库加载到内存,然后根据客户端的ip使用折半搜索改ip所在的城市,用java做非常的方便,先把几兆的数据加载到内存中,然后每个线程都来请求就可以了。而对于fastcgi来就比较麻烦了,需要把这些数据加载每个fastcgi进程中,无辜浪费掉一堆内存。不过有得必有失,因为每个fastcgi只能同时处理一个请求,所以使用fastcgi就基本不需要考虑多线程的问题了。
通过几天时间的学习,确实使我更加了解了python以及django,但是ahuaxuan也知道要掌握
一门语言和技术需要的肯定是不止几天而已,几天可以说只是入门,说的不对的地方恳请大家批评指正.
[/size]
在rails里面进行多数据库应用真是方便极了,直接在模型里面声明即可,或许这就是ruby强大的地方,也就是说一个对象在建立之后甚至运行的过程中也可以修改它的属性(数据库连接)
这一点我也是深有感触啊,我们现在的应用中有涉及到到多数据库的,一个是 mysql的,一个是oracle的,之间进行数据交互什么的,方便极了,完全就感觉是一个数据库中进行的。
在rails里面进行多数据库应用真是方便极了,直接在模型里面声明即可,或许这就是ruby强大的地方,也就是说一个对象在建立之后甚至运行的过程中也可以修改它的属性(数据库连接)
python的用途非常多,比如说google很多应用都用到了python,还有我们的cdn也是用python,很多电影,比如星球大战也是用python,美国的航天局也用python,youtube也用python(据说用python的公司很容易被google收购,呵呵), ...,我为什么只挑我喜欢的那种呢,只是因为我喜欢它.
python 除了类函数定义中的self看着不顺眼外,还是相当好用的。我也用它,是因为公司的每个linux机子都有它,没ruby,而且python看着真简洁。
有关企业界的承认,也补充一些:
a) Mac机,还有大多数Linux都默认安装Python,很顺手。
b) 巨头支持。Google 互联网老大,公司内部中Python是官方的第三语言,有内部员工说他们是能用Python就用Python, 实在不行才用C++; Youtube 大部分是用 Python写的;著名Linux发行版Ubuntu的发行公司的官方语言,也是其创始人的首选语言;
c)其他还有Redhat Linux, 美国宇航局,金融系统如纽约股票交易所,摩根大通,电影动画制作如动画三巨头Disney,Pixar和DreamWorks,星球大战的特效公司ILM等一系列如雷灌耳的大公司中使用。桌面程序如流行程序BT下载客户端等。
ruby也是不错的,只是在比赛中慢了几步,又没啥特别突出的,ROR只是个概念,python也是足够灵活的,现在有对应的pylon和django;对未来的多核CPU还没注意到ruby有没有努力去适应。看看python的网络排名已经超过perl和c#,ruby掉出前十名。不过创业型或中小型企业还是可以考虑用rails的.
呵呵,这句话让我想起了某日剧里面的一个台词——“但是莉香也知道……” 楼主好可爱哦。
跑题了。。。
谢谢楼主分享,《理解专业程序员》和《代码大全》中都提到过掌握两门以上语言对提升程序员水平的巨大作用。支持楼主。
确实两者上手都挺快的,两者比较类似,我选择django的的原因是因为我选择了python,所以才选择了django,在python的web框架里,django不但开发速度快,而且运行速度也是最快的,稍后我会放出我的测试.
而说到为什么选python而没有选ruby,那么原因就太多了,因为python的用途非常多,比如说google很多应用都用到了python,还有我们的cdn也是用python,很多电影,比如星球大战也是用python,美国的航天局也用python,youtube也用python(据说用python的公司很容易被google收购,呵呵),当然这里更多的是个人喜好的问题,有的人喜欢ruby,有的人喜欢python,虽然我认为ruby现在还是没有python强大的,如果即使他们一样强大,我还是选择python,就象买剃须刀一样,功能一样,我为什么只挑我喜欢的那种呢,只是因为我喜欢它.
呵呵,和我一样,最终选择了python
确实两者上手都挺快的,两者比较类似,我选择django的的原因是因为我选择了python,所以才选择了django,在python的web框架里,django不但开发速度快,而且运行速度也是最快的,稍后我会放出我的测试.
而说到为什么选python而没有选ruby,那么原因就太多了,因为python的用途非常多,比如说google很多应用都用到了python,还有我们的cdn也是用python,很多电影,比如星球大战也是用python,美国的航天局也用python,youtube也用python(据说用python的公司很容易被google收购,呵呵),当然这里更多的是个人喜好的问题,有的人喜欢ruby,有的人喜欢python,虽然我认为ruby现在还是没有python强大的,如果即使他们一样强大,我还是选择python,就象买剃须刀一样,功能一样,我为什么只挑我喜欢的那种呢,只是因为我喜欢它.
这样的url定义意味着你可以通过诸如:http://localhost/user/23/的形式访问一个用户的信息。
然后定义如下一个函数:
在上面的函数中,id就是通过url传过来的命名参数,函数获取信息后,将user和groups信息交给模板user_detail.html进行数据渲染后返回客户端。
这种方式能否再进一步,就是正则表达式中包含method的信息,这样我就可以指定执行views中的哪个函数了,比如说
http://localhost/user/23/edit/就表示执行views中的edit方法,虽然看上去比较怪异,不过要比加methodName这种方式好多了,虽然不能restful,那url看起来比正文中看起来好了很多.
一个普通的java程序员,从不懂python和django,在没有任何第三者予以帮助的情况下,如果能够流畅的阅读英语,一般一个星期左右,就能基本掌握基于django的简单的web应用开发。
这个我想式django一大优势之一,入门确实很简单,不过不清楚django为什么没有在国内有运用起来,只有很少的网站在使用django.
事实上,完成整个例子,这个例子中还包括验证码,文件上传等,我只用了周末2天和周一到周五每天1个小时.这么好的东西为啥用的人不多呢?
之前我内心曾激烈斗争过,到底是学ror,还是django,斗争了相当长一段时间之后,我还是选择了django.
我也在犹豫到底选择Diango 还是Ror ,楼主能否写一下详细的决定过程,你的理由就是上手快,但是RoR上手也快啊。谢谢
这个记得是讨论如何友好实现多链接的方法的
ror中ruby的语法太怪异,还有对于小日本的东西不感兴趣。
我喜欢用php的CI框架,简单明了。
把简单的事情搞复杂是java的专长。
开源无国界,收起狭隘的虚假的爱国情结。
ror中ruby的语法太怪异,还有对于小日本的东西不感兴趣。
我喜欢用php的CI框架,简单明了。
把简单的事情搞复杂是java的专长。
一 django的orm
如果有人问我最喜欢django什么,我会耗不犹豫的告诉你是django的orm,这个想法的产生完全来自于我长时间来积累的对hibernate的“不满”,虽然从理智的角度来看,hibernate做的是非常的正确的,因为它并不是只针对互连网而产生的,它的主要市场应该还是在企业应用上,不过把它用在互联网并非不可以,只不过大家更多的时候会选择ibatis之类,因为不知道hibernate的人总是会说hibernate没有ibatis快(其实我最烦这个,片面的比较是没有意义的)。正是hibernate的目标是打造成java界一个全方位,全能的orm框架,所以的它学习曲线和使用的复杂度日益的提升,要完全掌握好hibernate不是一件容易的事情(不要告诉我你会点crud,知道点lazy load你就掌握好hibernate了),再回头来看django的orm,如果说要把hibernate说清楚需要800页的书,那么要把django的orm说清楚,200页就够了(事实上它的官方文档只有十几页的样子)。下面我举一个我正在做的例子,这里有一个自关联的对象(事实上django的orm是基于model,这点和ror不太一样,有人跟我讲过ror是数据库驱动),这个对象有一个父对象,通常我们的菜单会定义成这样的对象,这样的菜单可以无限级向下扩展:
class Category(models.Model): id = models.AutoField('id', primary_key=True) name = models.CharField(maxlength=50) code = models.CharField(maxlength=50) parentCategory = models.ForeignKey('self', 'id', null=True) enable = models.BooleanField() def __str__(self): return self.name class Admin: list_display = ('id', 'name', 'code', 'parentCategory')
Category中又定义的Admin是为django的Admin模块服务的。
瞧,我们定义的域模型只需要这些代码就够了,models.Model是父对象,所有的model对象都需要继承这个对象,这个对象提供了很多常用的数据库方法,不过不是基于sql的,还是基于对象的,如同Criteria一样。下面列出常用的一些查询Category的方法。
1,
引用
Category.objects.get(id = request.POST['category'])
查询category by id(从页面上传过来的)
2
categoryList = Category.objects.filter(code__contains = “a”,enable = True).order_by(“-id”)[0:5],按id倒序,查询enable属性为True的,且code中包含a的category,且取前5个,是不是有很强烈的criteria的味道
3
category.save()保存或者更新某个category对象(类似saveOrUpdate操作),充血模型,dao消失了。
4
category.delete()删除某个category对象,当然delete方法也是支持批量删除,比如
categorys.delete()
5 复杂的查询可以使用extra方法,例如:
Category.objects.extra(where=['id IN (3, 4, 5, 20)']),还可以使用字符替换法,如:
Category.objects.extra(where=['code=%s'], params=['a'])
当然django的orm提供了很多很常用的功能,这里不一一举例了,注意,这里我说的是提供了很多很常用的功能,至于hibenate中比较复杂的映射策略,在django中我并没有看到。但是我反而高兴我没有在django中找到这个功能,因为django本身的定位是快速的互连网开发,它不需要太多的关注这个领域很少出现的东西,这样带来的优点是学习曲线的降低和开发效率的提高。
二 django的模板
Django的模板可以说是非常的简洁,简洁到我不知道说什么好,简洁到看一下文档就能上手使用,在java中,freemarker和velocity我都用过,最复杂功能最强大的还是freemarker,支持jsp tag的嵌入让我们可以重用很多已经存在的组件,这一点我在之前的文章中也有过比较详细的描述(强强联手,看freemarker和displaytag的结合),由于了解,才有发言权,django的模板可以说是为互连网应用而诞生的,简洁及快速开发的特点让人情不自禁的喜欢。大多数模板语言的基本语法都是类似的,比如在freemarker中显示值是${},而在django是{{}},freemarker中if判断为<#if></#if>,而django中是
{% if msg %} Xx {% else %} Xx {% endif%}
再看看在django中渲染模板的方法,有两种:
第一种
def preparePublish(request): t = loader.get_template(publishInfo) return HttpResponse(t.render(Context({'categoryList' : None})))
第二种
c = Context({"categoryList":categoryList}) return render_to_response(indexPage, c)
render_to_response相当于封装了loader.get_template方法而已,所有的一切看上去都是那么的简单,模板无处不在,今天你模板了吗?
插一句题外话,关于jsp的题外话,不管是ruby,还是c++,还是python,在它们的web框架中都使用了模板,java中也有很多模板,我们最熟悉的是freemarker和velocity。这从一个侧面反映出我们web开发中的一个模式,那就是我们的view基本上是基于模板产生的,而jsp这个东西应该来说是时代的产物,在那个混乱的落后的时代产生的,不过很奇怪的是现在还有这么多人抱着它不放。
三 django的form
Django有两种form,一种是自己定义form class,还有一种是通过我们定义的model自动form class。
由于ahuaxuan只做 了一个信息发布的小例子,所以并不能全面的了解或者理解django中form的所有细节,不过从我涉及到的部分来讲,我对django的从模型创建表单的做法确实感到有比较大的局限性,因为很多时候,model中的数据 并不是从页面上来的,在这种情况下,form对象被构造出来之后,ahuaxuan还没有找到修改form中值的方法。
而自定义form类也比较麻烦,就是要写自己的model,这个和我们之前的做法比较不一样,这里的form代表我们java中的value object,model是domain object,在我们的ssh框架中我们通常把value object继承我们的domain object。虽然一堆又一堆的人提出了反对意见,说要把这两个对象分开,因为他们处在不同的层次中,但是从实践经验中,我们可以看到,这样做没有什么不好。而在django中自定义form和model分开的行为可能比较符合一些人的心理。
不过自定义forms也有比较让人称道的地方,在form中我们可以自定义验证规则,同时我们可以根据form对象直接生成页面中的内容,不过这一点其实也有比较麻烦的地方,就是如果要改变样式的时候就比较麻烦。不过总的来说django的form还是比较有特点的,而且一定程度上给我们带来了方便。
四 django的url转发
Django的url转发是基于正则表达式的,有的人叫好,有的人叫差,我就是叫差的那一拨人之一。url转发应该是一个非常清楚,非常明亮的事情,可是用上这个正则表达式匹配的东西之后,我郁闷了,所以我只能回到遥远的过去去绕过这个东东,我不用总可以了吧。
从目前目前掌握的知识来看,django的views里的东西其实是controller,为什么叫views?不得而知,不过一直这么沿用下来了,即使是在自然界,很多表面上去不太一样得东西,其实内部的原理是一样的,我就觉得django的views就是struts1.x中的action,为什么这样说呢,让我们来看看两段比较的代码,第一段是django的,第二段是struts1.x的:
def index(request): categoryList = Category.objects.filter(enable = True) for cate in categoryList: informationList = Information.objects.filter(category = cate)[0:5] cate.informationList = informationList c = Context({"categoryList":categoryList}) return render_to_response(indexPage, c)
――――――――――分隔线―――――――――――――――
public ActionForward getSechandIndex(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { setBargainIndex(request); return mapping.findForward("bargainHome"); }
从形式上来看,两者出奇的相似,比如说传入的参数等。我们知道python是面向对象的语言,但是事实上它也支持函数编程,如果def定义在class内部,那么就是对象的方法,否则,就可以认为是函数编程了,看看,我们的views里的东西都是函数,views其实是一个模块,这个模块我们可以认为是struts1.x中的action,而views中的函数可以认为是action中的方法。它们是远房亲戚。
那么说到这里,曲线救国的线也找到了,就是struts.1x中DispatchAction,我们只要在url后面追加一个methodName就可以指定我们要调用views中的哪个函数了。代码如下:
def execute(request): methodName = request.GET['methodName'] return getattr(mark.views, methodName)(request)
这个execute方法成为了所有的方法的入口(我们在urls.py中只需要这样定义:
(r'^$', 'inforplatform.bargin.views.execute'))
接着在execute方法中判断methodName的值,然后根据这个值找到对应的函数,再调用它,getattr类似于java中的反射,可以让我们动态调用任何我们想调用的函数(只要我们知道函数名的话)
这样我们在urls.py中只需要定义很少的值(有几个模块就定义几行就够了)就可以完成我们的项目了,以后维护起来也没有这么麻烦和复杂。
一个小小的缺憾是没有自带restful,不过听说有一个插件可以支持。
六 admin
Django的admin功能号称是django的杀手级特性(killer feature),这一说可以说是恰如其分,毫不夸张的,从我做的这个例子来看,当我做网站的时候,基本上只需要关注前台页面的展示这部分,后台的功能基本上都自动有了,比如我做的例子是一个二手信息发布平台,category是二手信息的类型,还有一个information类,和category是多对一的关系,那么在后台,category和information的crud就自动生产了,由于category本身是一个自关联,所以在admin中 add category的时候,admin会根据我model的定义,自动要求选择一个parentCategory,而在add information的页面上,admin会要求我选择一个category来完成对一个information的创建,而以前在java中,这些工作都需要自己完成,当然也有很多工具可以自动生产crud,不过这些开源的工具基本上都是针对单个model的,而且生成的代码需要很大修改才能真正的把功能跑起来,最重要的一点是不能自动生成关联关系的管理。当然我也见过有公司做了基于数据库驱动的代码生产器,能生成完整可用的代码和页面,也包括关联关系的处理,不过由于语言特性的区别,在开发的时候我们还是要不停的重启server才能显示出效果来,虽然在技术上,为ssh实现这个功能并不难,但是会消耗不少时间在上面,消耗了很多时间的话,很少就有公司将其贡献出来了。所以个人认为django在这个功能上做得还是非常不错的,尤其这个功能可以节省开发者很多的时间。甚至有些时候,项目可以双线执行,用户通过admin输入数据,程序员开发前台,这样,前台功能做完之后,数据也有了,基本可以测试上线了。在需要快速开发的小项目上,这个特性显得尤其重要,因为django产生得时候就是基于这个场景。
当然有时候后台也没有这么简单,不过还好,admin提供了扩展的功能,我们可以自己写扩展的代码,然后集成到admin中去,不过事实上除了能改变admin的模板,我们不能改变任何admin的代码,不过我时常在想,如果admin支持代码自动生成的功能,那岂不是很美妙,我们可以随意的修改后台的功能了,否则我们就需要自己写代码,不如在生成的代码上扩展方便。
要使用admin,必须打开django的权限模块,这里简单介绍一下权限模块,django自带了一个权限模块,这个权限模块中的model对于熟悉权限这块的人来说再熟悉不过了,user,group,permission,user和group多对多,group和permission多对多,在acegi中,我们通常这样定义,user,role,resource,这个和django中的权限是一样的,不过在django中默认的permission的粒度是非常的粗了,是基于model的,如果我们要更细的权限模块,那么就需要自己扩展了。
总的来说admin给我的惊喜大于失望,虽然有点小小的不满意,但是总体来说还是非常赞的
五 部署
在这部分开始之前我也想聊聊之前我们一直在讲,而且将来还一直会讲下去的一个话题――状态。
之前我们一直在讨论,把用户的状态保存在一个集中的地方,尤其是大规模集群部署的情况下,同样,对于django来说亦是如此,可以说这条金科玉律不只是针对某种针对某个语言,某个框架,它应该是更高层次的一种理念。那么我们可以把状态放到什么地方呢,目前一些流行的选择是DB(内存表,或实体表),memcached,或者cookie,但这几种选择并不是可以随便互换的,比如业务数据较多的情况下,放在cookie中不是很合适,因为有可能超出cookie大小的限制,那么放在memcached中,很遗憾,memcached(使用slab的情况下)中也有它自己的限制,如果状态数据大小跨度较大,那么丢数据的情况有可能发生,ahuaxuan很久之前在测试环境下就碰到过这种情况,由于线上memcached开得较大,所以没有出现这种情况,关于这种事件发生得内部原因在ahuaxuan的另外一篇文章中已经有了非常详细的描述。那么放在DB上呢,显然,DB的压力也是我们需要考虑的问题之一。当然除了这些主流的选择之外,我们其他选择还有很多,比如memcachedb,或者timesten,或者其他等等,但是对于状态这种东西,尤其状态数据比较重要的情况下,我们一定要深入研究并理解状态数据的存储技术,否则可能会遇到我们异想不到的情况,比如很久之前我想破头也不会想到memcached是LRU是针对某个slab的(而且我还要插一句,LRU的时候其实并不是遍历slab中的chunk链表,而且只遍历最开始的50个数据而已,这样做纯粹是为了速度)。
目前对django来说基本上有两种部署策略,
第一种是利用mod_python将django运行在apache进程中,还有一种是webserver+fastcgi,这两种方式各有优缺点,在mod_python模式中,我们的webserver必须使用apache,apache在webserver这一领域已经独占鳌头很多年了,市场占有率也是远远的超过其他的webserver,不过近几年来,又崛起了几个其他的webserver,其中比较出名的是ligttpd和nginx,它们都以高性能和低内存消耗对apache发出了挑战,而mod_python是apache的插件,使用这种方式就把我们的webserver限定在apache上了,不过还好apache+mod_python也是非常的稳定的方案了。
第二种就是webserver+fastcgi,这里的webserver就可以随意选择了,大多数的webserver对提供了对fastcgi的支持,比如我们耳熟能详的lighttpd和nginx,而且据称在很多情况下,FastCGI能够提供比mod_python更为优越的安全性和效能。针对小型站点,相对于Apache来说FastCGI更为轻量级。据称qq的个人空间就是c++加fastcgi实现的,哦,这样做的优势在哪里呢,c++的处理速度将会非常的快,也就是说每个fastcgi处理一个请求将会非常快速,比如使用python需要50毫秒,c++处理这个请求有可能只需要20毫秒(这个例子未必准确,只是为了说明fastcgi的特性),虽然在开发上c++比较麻烦一点,不过在性能上,c++肯定是no1了,从这个例子上我们可以看到,使用fastcgi速度取决于处理一次请求的速度(废话,哪个不是这样)。
我们来看一下使用fastcgi的一般模式:1、WEB服务器收到客户端的页面请求 2、WEB服务器将这个页面请求委派给一个FastCGI 外部进程(WEB服务器于FastCGI之间是通过socket来连接通讯的) 3、FastCGI外部进程得到WEB服务器委派过来的页面请求信息后进行处理,并且将处理结果(动态页面内容)返回给WEB服务器 4、Web服务器将FastCGI返回回来的结果再转送给客户端浏览器。
对我们来说第3步是我们最需要关注的,因为第3步的速度严重影响着整个性能。由于fastcgi是基于进程的,所以,我们要根据我们的应用来开启数量合适的fastcgi进程,多开了是对资源的浪费,少开了就影响性能,这个类似我们在tomcat中开启处理请求的thread一样,只不过tomcat中的request handler thread在配置起来显然更加方便,因为我们只要关注线程池中最大的可以容纳的线程数,最大空闲线程数等就行了。
当然fastcgi对ahuaxuan这类刚刚跨出java世界的人来说有些不爽的地方,因为基于进程的东东共享数据比较麻烦,比如写一个ip查询的组件,功能是这样的,把ip地址库加载到内存,然后根据客户端的ip使用折半搜索改ip所在的城市,用java做非常的方便,先把几兆的数据加载到内存中,然后每个线程都来请求就可以了。而对于fastcgi来就比较麻烦了,需要把这些数据加载每个fastcgi进程中,无辜浪费掉一堆内存。不过有得必有失,因为每个fastcgi只能同时处理一个请求,所以使用fastcgi就基本不需要考虑多线程的问题了。
通过几天时间的学习,确实使我更加了解了python以及django,但是ahuaxuan也知道要掌握
一门语言和技术需要的肯定是不止几天而已,几天可以说只是入门,说的不对的地方恳请大家批评指正.
[/size]
评论
61 楼
qichunren
2009-08-10
下一站,火星 写道
diegoyun 写道
郁闷的是,我鼓动别人学python学django,但我没发现在django里如何解决我的应用需求.
如,多数据库应用. 如果在spring里,通过aop拦截数据源名字可以自动切换数据库.对action层面的类来说,不需手动切换数据库.
不知道django如何解决多数据库的问题?
请教各位牛牛.
如,多数据库应用. 如果在spring里,通过aop拦截数据源名字可以自动切换数据库.对action层面的类来说,不需手动切换数据库.
不知道django如何解决多数据库的问题?
请教各位牛牛.
在rails里面进行多数据库应用真是方便极了,直接在模型里面声明即可,或许这就是ruby强大的地方,也就是说一个对象在建立之后甚至运行的过程中也可以修改它的属性(数据库连接)
这一点我也是深有感触啊,我们现在的应用中有涉及到到多数据库的,一个是 mysql的,一个是oracle的,之间进行数据交互什么的,方便极了,完全就感觉是一个数据库中进行的。
60 楼
下一站,火星
2009-08-09
diegoyun 写道
郁闷的是,我鼓动别人学python学django,但我没发现在django里如何解决我的应用需求.
如,多数据库应用. 如果在spring里,通过aop拦截数据源名字可以自动切换数据库.对action层面的类来说,不需手动切换数据库.
不知道django如何解决多数据库的问题?
请教各位牛牛.
如,多数据库应用. 如果在spring里,通过aop拦截数据源名字可以自动切换数据库.对action层面的类来说,不需手动切换数据库.
不知道django如何解决多数据库的问题?
请教各位牛牛.
在rails里面进行多数据库应用真是方便极了,直接在模型里面声明即可,或许这就是ruby强大的地方,也就是说一个对象在建立之后甚至运行的过程中也可以修改它的属性(数据库连接)
59 楼
taupo
2009-06-19
刚刚看了几天的python和django,感觉不错,不过对于django总感觉orm部分不公开,很不放心
58 楼
fjlyxx
2009-01-16
我只是用PYTHON做一些测试工具,其他的还真没做过.
57 楼
sky.zha
2008-12-31
看来django的orm还没有grails好玩
56 楼
jjx
2008-11-24
1. 顺序匹配不懂你具体所指,但django的url定义可以命名,然后用reverse得到
2. 这个倒是没办法,不过仔细去想view其实也很恰当,view 是为真正的表现层服务的
3. model的方法和manager类的方法均是很好的放置业务逻辑的地方.这没有什么不好,喜欢ddd开发的将逻辑放到model中,喜欢transaction script将逻辑放到manager类中
4. 模板可以用mako ,但其实django的模板还是有好处的,最起码我这个项目中,网页设计师能看的懂这些标记,要是用mako,只能程序员自己整了
5. orm 没办法,如果要dba 友好,只有用sqlalchemy的sql expression,我现在都是混用两者的
6. 其实有很简单的hack 的google一下就有,django 的资源其实挺多的
2. 这个倒是没办法,不过仔细去想view其实也很恰当,view 是为真正的表现层服务的
3. model的方法和manager类的方法均是很好的放置业务逻辑的地方.这没有什么不好,喜欢ddd开发的将逻辑放到model中,喜欢transaction script将逻辑放到manager类中
4. 模板可以用mako ,但其实django的模板还是有好处的,最起码我这个项目中,网页设计师能看的懂这些标记,要是用mako,只能程序员自己整了
5. orm 没办法,如果要dba 友好,只有用sqlalchemy的sql expression,我现在都是混用两者的
6. 其实有很简单的hack 的google一下就有,django 的资源其实挺多的
55 楼
diogin
2008-11-24
用了将近一个月的Django,说实话开发速度跟我自己写的PHP框架比起来还有点差距。说说几个不好的地方:
1、urls.py的正则表达式匹配有两个弊端:顺序匹配和没有反推功能。正则的顺序匹配对于对算法要求比较严格的人来说是很难接受的。另外反推功能(从view推出url以便于在模板中使用)的缺失也不方便,可能是我只是浅尝则止,没有发现对应的反推函数;
2、把action称为view,这增加了名词的混淆;
3、缺少service层,不容易复用业务组件,此时的hack是把service扔进model,这会造成混乱;
4、模板语言太简陋,ifequal不支持or之类的操作,也不支持大小比较操作,等等,很多时候视图逻辑只能进入action(Django里称为view),增加了耦合度;
5、orm层封装得有点厚,对DBA来说增加了优化数据库的难度;
6、不支持同时运行多种数据库和多台数据库。
以上只是我一段时间里的一点体会,肯定有不正确之处,希望各位帮忙指正。
1、urls.py的正则表达式匹配有两个弊端:顺序匹配和没有反推功能。正则的顺序匹配对于对算法要求比较严格的人来说是很难接受的。另外反推功能(从view推出url以便于在模板中使用)的缺失也不方便,可能是我只是浅尝则止,没有发现对应的反推函数;
2、把action称为view,这增加了名词的混淆;
3、缺少service层,不容易复用业务组件,此时的hack是把service扔进model,这会造成混乱;
4、模板语言太简陋,ifequal不支持or之类的操作,也不支持大小比较操作,等等,很多时候视图逻辑只能进入action(Django里称为view),增加了耦合度;
5、orm层封装得有点厚,对DBA来说增加了优化数据库的难度;
6、不支持同时运行多种数据库和多台数据库。
以上只是我一段时间里的一点体会,肯定有不正确之处,希望各位帮忙指正。
54 楼
sleekengine
2008-11-22
ahuaxuan 写道
python的用途非常多,比如说google很多应用都用到了python,还有我们的cdn也是用python,很多电影,比如星球大战也是用python,美国的航天局也用python,youtube也用python(据说用python的公司很容易被google收购,呵呵), ...,我为什么只挑我喜欢的那种呢,只是因为我喜欢它.
python 除了类函数定义中的self看着不顺眼外,还是相当好用的。我也用它,是因为公司的每个linux机子都有它,没ruby,而且python看着真简洁。
有关企业界的承认,也补充一些:
a) Mac机,还有大多数Linux都默认安装Python,很顺手。
b) 巨头支持。Google 互联网老大,公司内部中Python是官方的第三语言,有内部员工说他们是能用Python就用Python, 实在不行才用C++; Youtube 大部分是用 Python写的;著名Linux发行版Ubuntu的发行公司的官方语言,也是其创始人的首选语言;
c)其他还有Redhat Linux, 美国宇航局,金融系统如纽约股票交易所,摩根大通,电影动画制作如动画三巨头Disney,Pixar和DreamWorks,星球大战的特效公司ILM等一系列如雷灌耳的大公司中使用。桌面程序如流行程序BT下载客户端等。
ruby也是不错的,只是在比赛中慢了几步,又没啥特别突出的,ROR只是个概念,python也是足够灵活的,现在有对应的pylon和django;对未来的多核CPU还没注意到ruby有没有努力去适应。看看python的网络排名已经超过perl和c#,ruby掉出前十名。不过创业型或中小型企业还是可以考虑用rails的.
53 楼
pipilu
2008-11-18
ahuaxuan 写道
但是ahuaxuan也知道要掌握一门语言和技术需要的肯定是不止几天而已
呵呵,这句话让我想起了某日剧里面的一个台词——“但是莉香也知道……” 楼主好可爱哦。
跑题了。。。
谢谢楼主分享,《理解专业程序员》和《代码大全》中都提到过掌握两门以上语言对提升程序员水平的巨大作用。支持楼主。
52 楼
sky.zha
2008-11-17
决定选python
51 楼
kjhot
2008-11-14
ahuaxuan 写道
songk 写道
我也在犹豫到底选择Diango 还是Ror ,楼主能否写一下详细的决定过程,你的理由就是上手快,但是RoR上手也快啊。谢谢
确实两者上手都挺快的,两者比较类似,我选择django的的原因是因为我选择了python,所以才选择了django,在python的web框架里,django不但开发速度快,而且运行速度也是最快的,稍后我会放出我的测试.
而说到为什么选python而没有选ruby,那么原因就太多了,因为python的用途非常多,比如说google很多应用都用到了python,还有我们的cdn也是用python,很多电影,比如星球大战也是用python,美国的航天局也用python,youtube也用python(据说用python的公司很容易被google收购,呵呵),当然这里更多的是个人喜好的问题,有的人喜欢ruby,有的人喜欢python,虽然我认为ruby现在还是没有python强大的,如果即使他们一样强大,我还是选择python,就象买剃须刀一样,功能一样,我为什么只挑我喜欢的那种呢,只是因为我喜欢它.
呵呵,和我一样,最终选择了python
50 楼
ahuaxuan
2008-11-14
songk 写道
我也在犹豫到底选择Diango 还是Ror ,楼主能否写一下详细的决定过程,你的理由就是上手快,但是RoR上手也快啊。谢谢
确实两者上手都挺快的,两者比较类似,我选择django的的原因是因为我选择了python,所以才选择了django,在python的web框架里,django不但开发速度快,而且运行速度也是最快的,稍后我会放出我的测试.
而说到为什么选python而没有选ruby,那么原因就太多了,因为python的用途非常多,比如说google很多应用都用到了python,还有我们的cdn也是用python,很多电影,比如星球大战也是用python,美国的航天局也用python,youtube也用python(据说用python的公司很容易被google收购,呵呵),当然这里更多的是个人喜好的问题,有的人喜欢ruby,有的人喜欢python,虽然我认为ruby现在还是没有python强大的,如果即使他们一样强大,我还是选择python,就象买剃须刀一样,功能一样,我为什么只挑我喜欢的那种呢,只是因为我喜欢它.
49 楼
songk
2008-11-14
ahuaxuan 写道
bluecrystal 写道
urlpatterns = patterns('', (r'^user/(?P<id>\d+)/$', 'mysite.user.views.detail'), }
这样的url定义意味着你可以通过诸如:http://localhost/user/23/的形式访问一个用户的信息。
然后定义如下一个函数:
def detail(request, id): user = User.objects.get(pk=id) groups = user.groups.order_by("-groupName") return render_to_response("user_detail.html", {"user":user, "groups":groups})
在上面的函数中,id就是通过url传过来的命名参数,函数获取信息后,将user和groups信息交给模板user_detail.html进行数据渲染后返回客户端。
这种方式能否再进一步,就是正则表达式中包含method的信息,这样我就可以指定执行views中的哪个函数了,比如说
http://localhost/user/23/edit/就表示执行views中的edit方法,虽然看上去比较怪异,不过要比加methodName这种方式好多了,虽然不能restful,那url看起来比正文中看起来好了很多.
bluecrystal 写道
一个普通的java程序员,从不懂python和django,在没有任何第三者予以帮助的情况下,如果能够流畅的阅读英语,一般一个星期左右,就能基本掌握基于django的简单的web应用开发。
这个我想式django一大优势之一,入门确实很简单,不过不清楚django为什么没有在国内有运用起来,只有很少的网站在使用django.
事实上,完成整个例子,这个例子中还包括验证码,文件上传等,我只用了周末2天和周一到周五每天1个小时.这么好的东西为啥用的人不多呢?
之前我内心曾激烈斗争过,到底是学ror,还是django,斗争了相当长一段时间之后,我还是选择了django.
我也在犹豫到底选择Diango 还是Ror ,楼主能否写一下详细的决定过程,你的理由就是上手快,但是RoR上手也快啊。谢谢
48 楼
剑事
2008-11-09
ahuaxuan 写道
从这个上面看,好像django现在是支持多数据库的:
http://groups.google.com/group/django-developers/browse_thread/thread/9f0353fe0682b73
http://groups.google.com/group/django-developers/browse_thread/thread/9f0353fe0682b73
这个记得是讨论如何友好实现多链接的方法的
47 楼
ahuaxuan
2008-11-08
从这个上面看,好像django现在是支持多数据库的:
http://groups.google.com/group/django-developers/browse_thread/thread/9f0353fe0682b73
http://groups.google.com/group/django-developers/browse_thread/thread/9f0353fe0682b73
46 楼
zbird
2008-10-27
django设计的最初应当没有考虑过使用多个数据库的情况,所以一直没有什么比较好的解决方案。
据说有过支持多库的分支,但似乎也没什么动静。
如果硬要支持,可以不使用django的ORM,手动管理数据库连接。
只是这样Django的优势已丢失大半,似乎也没多少意思。
据说有过支持多库的分支,但似乎也没什么动静。
如果硬要支持,可以不使用django的ORM,手动管理数据库连接。
只是这样Django的优势已丢失大半,似乎也没多少意思。
45 楼
diegoyun
2008-10-27
郁闷的是,我鼓动别人学python学django,但我没发现在django里如何解决我的应用需求.
如,多数据库应用. 如果在spring里,通过aop拦截数据源名字可以自动切换数据库.对action层面的类来说,不需手动切换数据库.
不知道django如何解决多数据库的问题?
请教各位牛牛.
如,多数据库应用. 如果在spring里,通过aop拦截数据源名字可以自动切换数据库.对action层面的类来说,不需手动切换数据库.
不知道django如何解决多数据库的问题?
请教各位牛牛.
44 楼
ThinkInJava
2008-10-27
看来不错,有空学习学习
43 楼
qubic
2008-10-23
kevincool998 写道
robbin 写道
python是个介于Java和Ruby之间的语言,比Java要灵活的多,比Ruby又严谨的多。可能是我写惯了ruby代码了,总觉得python代码不如ruby那么好玩。
如果你要介绍django这些最基本的MVT架构,其实是不如Rails那么好用的,但是django的模块化要比Rails好,值得学习。
如果你要介绍django这些最基本的MVT架构,其实是不如Rails那么好用的,但是django的模块化要比Rails好,值得学习。
ror中ruby的语法太怪异,还有对于小日本的东西不感兴趣。
我喜欢用php的CI框架,简单明了。
把简单的事情搞复杂是java的专长。
开源无国界,收起狭隘的虚假的爱国情结。
42 楼
kevincool998
2008-10-23
robbin 写道
python是个介于Java和Ruby之间的语言,比Java要灵活的多,比Ruby又严谨的多。可能是我写惯了ruby代码了,总觉得python代码不如ruby那么好玩。
如果你要介绍django这些最基本的MVT架构,其实是不如Rails那么好用的,但是django的模块化要比Rails好,值得学习。
如果你要介绍django这些最基本的MVT架构,其实是不如Rails那么好用的,但是django的模块化要比Rails好,值得学习。
ror中ruby的语法太怪异,还有对于小日本的东西不感兴趣。
我喜欢用php的CI框架,简单明了。
把简单的事情搞复杂是java的专长。
发表评论
-
使用netbeans来开发django应用
2009-03-22 12:03 5173周六,朋友介绍我使用netbeans来开发django应用,于 ... -
闲来无聊,用python抓取天气信息,简单就是美啊
2009-02-06 11:39 5556/** * 作者:张荣华 * 日期:2009-02-26 ** ... -
在top监视窗口显示Django当前正在执行的请求URL
2008-12-03 23:06 1501在top监视窗口显示Django当前正在执行的请求URL ... -
django,性能测试,以及对fastcgi下进程模型和线程模型的分析
2008-11-15 16:29 5747/** *作者:张荣华 *日期:2008-11-15 * ... -
完善坛子工具库之--python版memcached遍历脚本
2008-10-22 22:39 2749今天看到robbin大哥用ru ... -
why,how日志监控(附ahuaxuan用python写的日志分析器)
2008-10-21 17:16 2405/** *作者:ahuaxuan *日期:2008-10- ...
相关推荐
我特意为大家准备了一份可运行的Django博客源码Demo,旨在帮助各位小伙伴更加快速地掌握Python编程,让大家在学习的道路上走得更加顺畅,快速实现从入门到精通的转变。
Python程序设计初识Pyth全文共13页,当前为第1页。Python程序设计初识Pyth全文共13页,当前为第1页。Python程序设计初识Pyth... Python程序设计初识Pyth全文共13页,当前为第1页。 Python程序设计初识Pyth全文共13页...
1.Django的历史 2.Django的设计哲学 3.Python和Django的开发之美 4.Django主要应用以及简单介绍
├─(143) 08 python全栈3 day58 DjangoForm组件初识.avi ├─(144) day58课上所有.rar (23)\\python全栈day51-60\\python全栈s3 day59;目录中文件数:8个 ├─(145) 01 python全栈3 day59.avi ├─(146) 02 python...
最新Python3.5零基础+高级+完整项目(28周全)培训视频学习资料;本资料仅用于学习。 【课程内容】 第1周 开课介绍 python发展介绍 第一个python程序 变量 字符编码与二进制 字符编码的区别与介绍 用户交互程序 if ...
│ │ ├02 python s14 day2 模块初识.avi │ │ ├03 python s14 day2 模块初识2.avi │ │ ├04 python s14 day2 pyc是什么.avi │ │ ├05 python s14 day2 python数据类型.avi │ │ ├06 python s14 day2 bytes...
01.初识Python.md 02.语言元素.md 03.分支结构.md 04.循环结构.md 05.构造程序逻辑.md 06.函数和模块的使用.md 07.字符串和常用数据结构.md 08.面向对象编程基础.md 09.面向对急进阶.md 10.图形用户界面和游戏开发....
06 Python初识以及变量 07 Python条件语句和基本数据类型 08 Python while循环语句以及练习题 09 练习题讲解 第10章 01 上节内容回顾以及补充 02 上周作业实现 03 Pycharm的安装和使用 04 Python 运算符 05 Python...
初识Python.md Day01-15\02.语言元素.md Day01-15\03.分支结构.md Day01-15\04.循环结构.md Day01-15\05.构造程序逻辑.md Day01-15\06.函数和模块的使用.md Day01-15\07.字符串和常用数据结构.md Day01-15\08.面向...
2.2.2 初识Thrift 33 2.3 小结 34 第3章 NoSQL接口与交互 36 3.1 没了SQL还剩什么 36 3.1.1 存储和访问数据 37 3.1.2 MongoDB数据存储与访问 37 3.1.3 MongoDB数据查询 41 3.1.4 Redis数据存储与访问 43 ...