- 浏览: 639671 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
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]
py无所不能,但是我还没发现用py而不能用Ruby搞定的事情,用Ruby在web上很火来证明py的前途无量,这比较搞。py很强大,不是以贬低Ruby为前提,否则就是zhuangbility
单从语言角度来看,确实没有什么py能做而ruby不能做的。但是现实中,由于MRI的某些缺陷,使得ruby难以深入到许多领域。
PS:我倒觉得Ruby取代Perl更甚于Py取代Perl,因为在Perl大展手脚的地方,恰恰也是Ruby的强项。
py无所不能,但是我还没发现用py而不能用Ruby搞定的事情,用Ruby在web上很火来证明py的前途无量,这比较搞。py很强大,不是以贬低Ruby为前提,否则就是zhuangbility
select_related这样也就基本满足需求了
另外就是extra了,这个灵活性不是很好,大家是否也可以讨论讨论
extra 还好吧,比如写个 sum:
products = Product.objects.extra(select={'temp':'sum(charge)'}).values('temp')[0]['temp']
宁波余姚的,呵呵
select_related这样也就基本满足需求了
另外就是extra了,这个灵活性不是很好,大家是否也可以讨论讨论
支持的不过你要写成select_related('fieldname')这种样子
不过这种方法有些问题,关联深度只能到1,在向下关联就要单独查询了
我也正在解决这个问题中,还没有找到合适的解决办法。
由于没有时间仔细研究,不敢妄自菲言。
一 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]
评论
41 楼
ahuaxuan
2008-10-15
perl我也没有用过,不过公司里其他部门还是一直在用,基本上也不是做web应用的,都是服务器上的维护等等,perl的一大优点是perl的工具集特别的多,凡是你能想到的,基本上它都有了,用起来就非常方便了(同事介绍的).
这一点python目前还比不过,而且python3000正在开发中,语法之类的变化挺大的,原来很多组件又都不能用了
这一点python目前还比不过,而且python3000正在开发中,语法之类的变化挺大的,原来很多组件又都不能用了
40 楼
hoorace
2008-10-14
用过一段时间的perl,不过现在基本是忘记了,最近学习了python,感觉比perl还是要好用一些,现在perl基本上是华人在维护更新了,不知道 拉里*沃尔 去做么事了!没有看过任何ror的资料,不发表评论。
39 楼
rubynroll
2008-09-30
dennis_zane 写道
fight_bird 写道
python最强大的恰恰是他的无所不能,在语言能力上又做到了严谨和效率的合理平衡,既有Java的强大、成熟,又有动态语言的一切优点,Ruby虽然在web很火,但也仅此而已,python前途无量。
py无所不能,但是我还没发现用py而不能用Ruby搞定的事情,用Ruby在web上很火来证明py的前途无量,这比较搞。py很强大,不是以贬低Ruby为前提,否则就是zhuangbility
单从语言角度来看,确实没有什么py能做而ruby不能做的。但是现实中,由于MRI的某些缺陷,使得ruby难以深入到许多领域。
PS:我倒觉得Ruby取代Perl更甚于Py取代Perl,因为在Perl大展手脚的地方,恰恰也是Ruby的强项。
38 楼
easygod
2008-09-28
用django给我带来最大的感受就是,有很多便利,也有很多郁闷的地方,
不过依靠python,很多功能的实现只需要调用现成的包,libs就行了,社区的力量很强大。
不过依靠python,很多功能的实现只需要调用现成的包,libs就行了,社区的力量很强大。
37 楼
fengzl
2008-09-28
据非正式统计 django高
36 楼
terranhao
2008-09-27
我想问,django和ror谁的开发效率高?
35 楼
dennis_zane
2008-09-21
fight_bird 写道
python最强大的恰恰是他的无所不能,在语言能力上又做到了严谨和效率的合理平衡,既有Java的强大、成熟,又有动态语言的一切优点,Ruby虽然在web很火,但也仅此而已,python前途无量。
py无所不能,但是我还没发现用py而不能用Ruby搞定的事情,用Ruby在web上很火来证明py的前途无量,这比较搞。py很强大,不是以贬低Ruby为前提,否则就是zhuangbility
34 楼
jjx
2008-09-19
extra目前用起来在处理复杂的连接上效率不高,而且不太顺利的处理子查询
直接用sql当然能解决一些问题,但这已经不是我们讨论django的本意了,再说,django对直接使用sql的支持并不怎么抽象
直接用sql当然能解决一些问题,但这已经不是我们讨论django的本意了,再说,django对直接使用sql的支持并不怎么抽象
33 楼
duka
2008-09-19
jjx 写道
select_related这样也就基本满足需求了
另外就是extra了,这个灵活性不是很好,大家是否也可以讨论讨论
extra 还好吧,比如写个 sum:
products = Product.objects.extra(select={'temp':'sum(charge)'}).values('temp')[0]['temp']
32 楼
fengzl
2008-09-18
宁波软件业基本没发现过好的公司~~我以前呆过两年.
不行就直接sql吧
不行就直接sql吧
31 楼
jjx
2008-09-18
fengzl 写道
再往下就不行了。至少我没办法了~
楼上的宁波工作?
楼上的宁波工作?
宁波余姚的,呵呵
select_related这样也就基本满足需求了
另外就是extra了,这个灵活性不是很好,大家是否也可以讨论讨论
30 楼
剑事
2008-09-18
left outer join 大数据量的时候容易阻塞
29 楼
fengzl
2008-09-18
多按了一下,重复提交了
28 楼
fengzl
2008-09-18
再往下就不行了。至少我没办法了~
楼上的宁波工作?
楼上的宁波工作?
27 楼
jjx
2008-09-18
谢谢提醒,试了一下,也可以在向下
使用__分隔
Menu.objects.order_by('sequence').exclude(visible=False).all().select_related('menuitem','security_key','menuitem__security_key')
像这里的menuitem__security_key
暂时未试再往下
使用__分隔
Menu.objects.order_by('sequence').exclude(visible=False).all().select_related('menuitem','security_key','menuitem__security_key')
像这里的menuitem__security_key
暂时未试再往下
26 楼
fengzl
2008-09-18
jjx 写道
ls的诸位有仔细研究过 select_related吗?
django的select_related实际作用不大,因为它有个最大的限制
Note that select_related() does not follow foreign keys that have null=True.
所以在在对外键允许为null的地方它都会每个属性对象单独发起一次查询
它不像hibernate用left outer join来处理,这是最大的问题
django的select_related实际作用不大,因为它有个最大的限制
Note that select_related() does not follow foreign keys that have null=True.
所以在在对外键允许为null的地方它都会每个属性对象单独发起一次查询
它不像hibernate用left outer join来处理,这是最大的问题
支持的不过你要写成select_related('fieldname')这种样子
不过这种方法有些问题,关联深度只能到1,在向下关联就要单独查询了
25 楼
jjx
2008-09-18
ls的诸位有仔细研究过 select_related吗?
django的select_related实际作用不大,因为它有个最大的限制
Note that select_related() does not follow foreign keys that have null=True.
所以在在对外键允许为null的地方它都会每个属性对象单独发起一次查询
它不像hibernate用left outer join来处理,这是最大的问题
django的select_related实际作用不大,因为它有个最大的限制
Note that select_related() does not follow foreign keys that have null=True.
所以在在对外键允许为null的地方它都会每个属性对象单独发起一次查询
它不像hibernate用left outer join来处理,这是最大的问题
24 楼
fengzl
2008-09-18
落后了阿,
现在可以这么做了:select_related(fields),或者select_related(depth=1)
不过好像对manytomany没用
现在可以这么做了:select_related(fields),或者select_related(depth=1)
不过好像对manytomany没用
23 楼
剑事
2008-09-18
select_related(3)
22 楼
bluecrystal
2008-09-17
fengzl 写道
model对引用对象属性的加载深度缺乏控制,
要么全部加载select_related()
要么在页面呈现的时候再去执行sql(n+1)
要么全部加载select_related()
要么在页面呈现的时候再去执行sql(n+1)
我也正在解决这个问题中,还没有找到合适的解决办法。
由于没有时间仔细研究,不敢妄自菲言。
发表评论
-
使用netbeans来开发django应用
2009-03-22 12:03 5204周六,朋友介绍我使用netbeans来开发django应用,于 ... -
闲来无聊,用python抓取天气信息,简单就是美啊
2009-02-06 11:39 5606/** * 作者:张荣华 * 日期:2009-02-26 ** ... -
在top监视窗口显示Django当前正在执行的请求URL
2008-12-03 23:06 1535在top监视窗口显示Django当前正在执行的请求URL ... -
django,性能测试,以及对fastcgi下进程模型和线程模型的分析
2008-11-15 16:29 5984/** *作者:张荣华 *日期:2008-11-15 * ... -
完善坛子工具库之--python版memcached遍历脚本
2008-10-22 22:39 2794今天看到robbin大哥用ru ... -
why,how日志监控(附ahuaxuan用python写的日志分析器)
2008-10-21 17:16 2449/** *作者:ahuaxuan *日期:2008-10- ...
相关推荐
本资源"【初识Django:轻松掌握Web框架实战技巧】源码资料"是为Python初学者量身定制的,通过一个可运行的Django博客应用实例,帮助大家深入理解Django框架的核心概念和实践技能。 首先,Django的核心组件包括模型...
总之,《初识Django CMS》将引导你进入Django CMS的世界,教会你如何使用这个强大的工具构建专业级的网站。无论你是Web开发者还是对Python和Django感兴趣的初学者,这本书都将是你宝贵的参考资料。通过学习,你将...
【初识Python】 在信息技术的学习中,Python是一种重要的编程语言,尤其对于八年级的学生来说,它是接触编程世界的一个理想入口。Python语言以其简洁明了的语法和强大的功能深受青睐。 1. **语言与程序设计语言** ...
1.Django的历史 2.Django的设计哲学 3.Python和Django的开发之美 4.Django主要应用以及简单介绍
**Django入门到放弃**,这是一段概括性的话语,暗示了从初识Django到深入学习的过程中可能会遇到的挑战。Django是一个基于Python的Web框架,它以其高效、安全和可扩展性著称,是许多开发者构建Web应用的首选工具。本...
这本书旨在帮助读者掌握Python编程的基础,无论你是编程新手还是对其他语言有一定了解,都能通过本书快速进入Python的世界。 Python是一种高级、通用的编程语言,以其简洁明了的语法和强大的功能而受到广大开发者的...
《初识Django》 Django,一个基于Python的开源Web框架,因其高效、安全且易于上手的特点,被广泛应用于各种规模的Web开发项目。本资料“Beginning Django”将引领初学者逐步深入理解并掌握这个强大的框架。 一、...
4. **初识Django (day15)** 这部分可能是对Django框架的简介,包括它的设计理念、优势以及与其它Web框架的比较。可能还涵盖了Django的快速启动指南,比如设置环境、创建项目和应用的步骤。 5. **数据类型和文件 ...
在Web开发中,Python以其灵活性和丰富的框架如Django、Flask、Tornado和Web2py脱颖而出。这些框架使得构建Web应用变得高效且易于维护。Python还支持XML技术,使其在处理和解析数据方面表现出色。 对于科学计算,...
【初识Django】 Django 的入门可能对新手来说有一定挑战,因为它需要一系列的安装和配置工作。与一些简单的Web框架如Karrigell相比,Django的功能更为全面,但也因此需要更多的前期准备。Django 拥有一个活跃的社区...
│ │ ├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...
- Web开发:Django和Flask是两个流行的Python Web框架,可以快速构建Web应用。 - 前端技术结合:Python可以通过HTML、CSS、JavaScript等前端技术生成动态网页,例如使用Jinja2模板引擎。 5. **Python进阶**: - ...
本章将引导读者进入OOP的世界,从定义类到实例化对象,再到继承和多态等高级特性,帮助读者建立起对OOP的理解和应用能力。 **第7章:组织程序** 随着项目的规模越来越大,如何有效地组织代码变得尤为重要。本章会...
在Python的世界里,PyPI(Python Package Index)是开发者们最常访问的资源库之一,它为全球的Python爱好者提供了丰富的第三方库。今天我们将聚焦于一个特定的库——django_layers-0.7.2,这个资源源自PyPI官网,它...
- **初识Django**: 这部分将引导你快速了解Django的基本概念,包括创建第一个项目、运行服务器、创建简单的视图和模板,以及如何访问数据库。 通过这份详尽的Django文档,你可以逐步学习并掌握这个强大的Web框架,...
《初识Python:从新手到专业》是一本旨在引导编程新手逐步掌握Python语言的专业教程。这本书不仅适合初学者,也适合有一定经验的程序员希望深入理解Python的各个方面。通过阅读本书和配套的源代码,读者可以全面了解...
1. **初识Django REST Framework** - REST(Representational State Transfer)是一种设计API的架构风格,强调资源的表述和状态转换。 - Django REST Framework 提供了丰富的工具集,如序列化器(Serializers)、...
在Python的世界里,初学者首先要了解的是Python的基础语法,包括变量、数据类型(如整型、浮点型、字符串、列表、元组、字典和集合)、控制结构(如if语句、for循环、while循环)以及函数的使用。Python以其简洁明了...
《初识Python 3rd Edition 源代码》是针对Python编程初学者的一份宝贵资源,它包含了Python基础教程第三版中的所有实例源码。这个压缩包文件"beginning-python-3ed-master"是该教程配套的源码仓库,旨在帮助读者通过...