我这几天在微博上写了一句话: 回归简单,即便开始反而会变得更加复杂。 回想起当年刚用Django写素材管理系统还历历在目,最近却已经逐渐脱离Django了。 成长总是分阶段的吧,勇敢的抛弃一些东西,接纳新的东西,也许就是成长了。 至于原因呢,也是我一直在总结的,大家可以一起看一下。 Django适合做中型项目,但却不适合小型和大型项目 为什么这么说呢?
- 对于中型项目来说,Django可以说提供了你需要用到的一切,session,orm,admin等等,只要你按照Django规定的思路来,你会发现开发和维护是如此顺手。
- 但是如果是小型项目呢? 我可能不需要session,我也不需要数据库,但是我却要为Django那些繁琐的东西配置半天。当我被这些繁琐而无用的东西搞晕的时候,我感觉更像是在搭积木,而不是在创造一个伟大的东西。
- 而对于大型项目来说,Django默认带的组件又满足不了需求,甚至连架构都可能要被替换,所以Django所自带的很多特性都将无法使用。 由于工作的关系,在大型项目中,有一类不得不说的服务,那就是SNS应用。 SNS应用的特点是什么?注册用户量极大,活跃很少。大批的用户蜂拥进入可能只是看一眼就再没回来,但是你的数据却因为这些无用的用户变得庞大无比。进而导致Django默认的那些Model,admin全部都形同虚设,Django的那些所谓的优势荡然无存。 博友反馈这里没说清楚,我再描述一下:
- 互联网的数据模型与关系数据模型不匹配。互联网数据更适合NoSQL,所以Admin对关系(外键、关联)的处理就没有任何用处了,而直接展示一个blob字段也并没有比用sql语句直观多少。(BTW,当数据量很大的时候,那种外键的下拉框慢得要死)
- Django并没有过多的考虑大数据量的问题,只支持了分库,不支持分表,Model的using语法也实在是丑陋。而且分库分表之后,Django的admin完全无法使用。再者在大用户量下 session 等机制都成为瓶颈。
这可是说是Django的定位,也可以说是Django的尴尬,所以必然要有其他框架来弥补这些缺陷。 所以我在很早便开始了尝试:
- web框架
- web.py,Flask,都用了一下,感觉还是不够简单,而终于,我发现了bottle。 bottle真的是个非常小巧的框架,只有一个文件,3000多行,代码我也基本上都读了一遍。
- ORM
- ORM我选用了简单的autumn,因为并不会用到复杂的关系数据。
- 模板
- 模板使用 jinja2,本身贴近django模板的语法,用起来也很熟悉。
- form类
- form类使用 WTForms。
一切看起来都很美好,似乎该有的功能都有了,但是如果真的如此简单,就不会有文章开头那段话了。 要使他们协作起来是件麻烦的事情,最麻烦的就是unicode的问题。 本着输入的最开始就要转成unicode,输出之前才转成bytes的原则,在使用这些类的时候有一下几点要遵循:
autumn_db.conn.connect( DATABASE['engine'], db=DATABASE['db'], user=DATABASE['user'], passwd=DATABASE['passwd'], host=DATABASE['host'], port=DATABASE['port'], use_unicode=True )
#Add-Begin by dantezhu in 2011-11-14 12:17:10 if db.conn.dbtype == 'mysql': values = [it.encode('utf8') if isinstance(it, unicode) else it for it in values] #Add-End
- autumn在连接MySQL的时候,一定要用 use_unicode=True,这样从MySQL获取的数据才默认是unicode的
- 使用WTForms的时候,要使用 form = RegForm(obj=request.forms) 的方式(bottle要使用0.10),这样才能form的数据才会默认就是unicode
- autumn的Model传入的参数必须是unicode,而仅仅如此还是不行的,由于MySQLdb的bug(我个人认为),要求excute函数传入的values必须是bytes类型,而sqlite3则要求传入unicode,所以我们要改一下autumn的代码,在query.py的190行增加代码:
- 并在connection.py第6行增加如下代码:
#Add-Begin by dantezhu in 2011-12-16 01:56:34 self.dbtype = dbtype #Add-End
OK,到此为止大功告成! 所有的组件都是我们可拆卸的,如果网站够简单,可以只有一个bottle;如果网站太复杂,我们可以任意的添加自己需要的模块,而且它们是真正做事的。 这还只是个开始,有新的想法会再和大家分享。
zukhz on #
不是很明白对于SNS那段的描述, 那些只注册用户换了一个框架就不存在了么? 还是想说明django的Model和Admin在数据量大的时候并不实用呢?
Reply
Dante on #
你好,针对你的疑问,我在文章中又补充了一下。
博友反馈这里没说清楚,我再描述一下:
互联网的数据模型与关系数据模型不匹配。互联网数据更适合NoSQL,所以Admin对关系(外键、关联)的处理就没有任何用处了,而直接展示一个blob字段也并没有比用sql语句直观多少。(BTW,当数据量很大的时候,那种外键的下拉框慢得要死)
Django并没有过多的考虑大数据量的问题,只支持了分库,不支持分表,Model的using语法也实在是丑陋。而且分库分表之后,Django的admin完全无法使用。再者在大用户量下 session 等机制都成为瓶颈。
Reply
zukhz on #
感谢 Dante 的补充, 很多时候在使用django的时候都明显有这个担忧, 或许目前所遇到的数据量感觉还没达到那个程度... : )
Reply
依云 on #
楼主用 Python 2.8 吧 ;-)
Reply
Dante on #
呀,依云是神马意思?木有2.8把???
Reply
依云 on #
Just Google it ;-)
Reply
Dante on #
2.8 final Never
这描述太牛逼了。。
Reply
波波 on #
我初学Python web框架,选择了web.py。听楼主一说,有空去感受一下bottle。
Reply
Dante on #
刚用的话,其实还是挺建议试一下Django的,毕竟从规范到自由是个不错的过程。一开始就太过自由的话,反而不太好。。
Reply
波波 on #
恩,楼主说的有道理。
Reply
guojing on #
我同意你的观点,说实话,不仅仅针对django来说了。django在我们内部只作为管理员和编辑使用,因为数据那块和admin确实做的不错。要说做大型网站,还是有很多不自在的地方的。
实际上任何想要做大而全的框架都会有这个问题。小的项目太大,大的项目基本上自有的功能完全不能用。还有死掉的pylons。
web.py不错,tornado,非阻塞的模型,也挺好。模版用mako,性能也不错。数据库我不用中间件,直接写sql,其实维护成本是一样的,加上cache。已经很完美了。
Reply
Dante on #
不知道为啥被当作垃圾评论了。。
对的,不用做大而全,选好一个点,做到极致是最好的~
Reply
Dante on #
BTW,bottle的作者很nice,反馈的bug修改的很及时
Reply
runforever on #
想请教一下楼主bottle适合做像twitter或者quora这样的网站吗?如果不行的话,它应该适合做像什么类型的网站,能举个例子说明一下吗?
Reply
Dante on #
这个问题,我也在考虑怎么回答比较适合。
其实对于bottle这么轻量的框架来说,并不存在适合哪种类型的网站的问题,twitter、quora的特殊性更多的是体现在他的架构和存储结构上。
就好像,你问nginx、apache 适合什么样的网站,其实并没有什么限制的。。
Reply
runforever on #
首先我是刚学python的web开发, 在bottle主页上的faq的这个问题 Is bottle suitable for complex applications? 根据问题的答案, 自己对复杂网站的感觉是一片空白, 想弄明白网站的复杂到底体现在什么地方,什么样的网站才是简单的呢??
Reply
Dante on #
其实所谓互联网网站的复杂大部分是由于大用户量和高并发带来的架构和存储的变化,这不是一两句话说的清楚的,最好找资料研究一下一些大型网站的设计。
Reply
nemo on #
Flask和bottle一样简单,但它的插件多,文档好,我在这两个之间选了很长时间,还在reddit上问了能不能把两个合并了。。。
两个用法基本是一样的,写的bottle代码基本改几处就能放在flask里了。
看看flask的源码就知道作者有多注重文档,
Reply
Dante on #
嗯,我一开始也是先用的flask,但是感觉flask设计的有点过于复杂了。。当然也可能是我还没有领会到他这样设计的精髓。。
Reply
moper on #
恩,都没有试过咧,重在需求了,我没经验哈
Reply
等你爽 on #
有关分表的问题,pininterest网站他们采用了纯分库架构都很好的解决了性能问题,因此他们不存在分表问题。
Reply
等你爽 on #
小项目配置繁琐完全可以通过自定制项目工程模板来解决。
当然如果你喜欢依赖,那另当别论。
Reply
等你爽 on #
django的admin有着许多很亮的创意,平凡的界面却蕴藏着非凡的可塑性,如果你善用django的消息机制(事件通知),就能通过简单的管理界面,简单的代码,实现复杂的管理操作功能。比如下面这个通过管理后台导入excel数据的功能。
@receiver(post_save, sender=models.ImportXls)
def import_xls (sender,**kwargs):
task=kwargs['instance']
if task.status>0:
return
task.status=1
task.save()
importMachine(task.xlsFile.path)
task.status=2
task.save()
Reply
阿小信大人 on #
bottle异常处理还是没有flask完善的。如果真的追求simple的话可以试试denied
Reply
Dante on #
是的,现在其实主要是在用django了,最大的原因是为了团队的人不用学习那么多第三方库,只要看一遍django的文档就可以了。。。denied我在pypi上搜了一遍没找到,在github才搜到,4年前了啊。。
Reply
Dante on #
不过看起来确实很轻巧,哈哈,可惜文档有点少,我试试
Reply
紫色大狗 on #
我也同意楼主的一些判断。django这个框架设计的目的本来就是新闻网站,所以django的意思就是在于快速开发一些中型项目,同时提供全面的各种功能。
Reply
Dante on #
是的,选择适合的工具。
Reply