阅读本文大概需要8分钟。
前几天Django发布了 3.1版本的更新,作为一个半吊子Django开发者,个人觉得这次是真的值得说一说了。
3.1的更新最重要的是下面两个改动:
支持异步views和middleware
ORM中JSONField所有数据库的支持
按照官方的说法,现在对于异步的支持已经扩展到views和middleware了,比如:
async def my_view(request):
await asyncio.sleep(0.5)
return HttpResponse('Hello, async world!')
这确实是一个相当大的改动。我们以前如果想使用Python的异步来开发Web应用,一般的选择有下面几个:
Tornado
Sanic
FastAPI
aiohttp
我也曾用上面的一些框架开发过一些应用,比如学生时代开发的基于Tornado的全异步社区应用Minos(https://github.com/phith0n/minos)。但是说实话,在后面接触过Django敏捷开发以后,我是不会再想使用老的开发框架了,原因也很简单,Django提供的方法、ORM、生态能帮助我在极短的时间快速开发出自己想做的应用,这是其他Web框架所无法比拟的。
当然,不支持异步也是Django一直以来被诟病的地方之一,我们如果需要基于Django开发websocket等异步相关的功能,还需要借助Channels这样的工具。
Django在从2.x就已经开始在慢慢设计由同步转变成异步相关的功能了,只不过用户在编写view和middleware的时候还一直不能使用async方法。这次相当于官方补齐了这一块的缺陷。
但是话说回来,Django 3.1的“异步”其实仍然是一个不可用的状态,原因我觉得如下:
ORM、Cache等重要的功能仍无法使用异步方法,在异步中使用同步的IO,有可能反而导致效率出现一些问题
websocket等长连接场景仍然没有一个独立的解决方案(指不再使用channels)
另外,异步这个事情,我个人一直持保留意见,原因我曾在分享《XRay旅行记 - 从内部项目到社区项目的蜕变》这个幻灯片的时候也提到过:如果能完美地实现异步与协程,当然是美好的,但现实情况是大多数人驾驭不好这一块的内容,而且大量第三方库也没有兼容这一块的内容。
所以我个人认为,Django走异步这条路,只要不影响现有的开发进程,我都是表示支持的,而且是迟早要走的路;至于异步对Django整体功能的优化,在没有完全解决长连接问题之前,都是影响不大的,我应该也暂时用不到。
相比于异步这块的进展,我期待已久的反而是JSONField的支持。这个功能我从Django 2.x开始就一直在盯了,有图为证????:
我曾用Django开发过数个Web应用,大多数情况下我在本地开发是不会用到Postgresql数据库的。借助Django ORM强大的框“数据库”属性,我通常在本地测试时都会使用Sqlite,这样不需要再额外启动任何服务,使用时最为方便。
但是,虽然ORM可以支持Sqlite、Mysql、Postgresql等多个数据库,但是不同数据库之间还是有一些细微差别的。
按照官方的说法,Django最适合的应该是Postgresql,因为Django官方兼容了大量PG中的数据结构:
Django provides support for a number of data types which will only work with PostgreSQL. There is no fundamental reason why (for example) a
contrib.mysql
module does not exist, except that PostgreSQL has the richest feature set of the supported databases so its users have the most to gain.
其中我们用到最多的就数JSONField
家族了,还有几个他的好兄弟,ArrayField
、HStoreField
。我通常会把一些不好关系化的对象直接保存在JSONField
中,让Postgres临时充当nosql数据库使用,然后复用Queryset中的类似__isnull
、__key
这样的功能来当关系型数据库字段查询,十分方便。
只是一旦我们有使用到JSONField
,那么数据库就被限定在Postgres了,因为之前Django并不支持其他数据库的json方法。
这也给我本地开发带来了诸多不便,毕竟我习惯于本地使用Sqlite做数据库。虽然网上有一些简单的解决方案,比如https://github.com/rpkilby/jsonfield,但实际上这种第三方库只是解决了JSON的储存问题,没有解决Queryset相关的方案,所以其实和直接储存在TextField里没有太大区别。
3.1这次更新直接解决了这一大问题,而且内部使用到了不同数据库内置的JSON解决方案,除了对数据库版本有一些要求以外,几乎就是平滑更新,这是又一个让我十分喜爱Django ORM的原因。
我觉得现在慢慢地被Django ORM宠坏了,写原生SQL语句总感觉十分别扭,不知道这是一件好事还是坏事呢?????
Minos:https://github.com/phith0n/minos
Django Channels:https://channels.readthedocs.io/en/latest/
《XRay旅行记 - 从内部项目到社区项目的蜕变》:https://www.leavesongs.com/SHARE/xray-introduce.html
最后发一个小投票,看看谁是大家最喜欢的Python Web开发框架?