在使用 Flask 开发了较多 Web API 以后,最近突然想在项目里再尝试一下 Django + REST framework 的架子。因为在很多弱需求下,这套框架总是更能让需求方感到安心[摊手]。自己也希望通过这次重新接触,加深对开发模式(套路)的理解。
项目是一个 CMS 系统,特点是 PV 较小,对延迟也不敏感,但业务逻辑较复杂(预计最终数据表的数量在50+),且需求并不明确(表结构和接口变化较快),另外接口稳定性要求很高。为了适应这种需求,希望能够把项目模块化,或者时髦一点叫做微服务,避免过度耦合导致后期无法维护。(友商们的该系统都已进入这种状态)
最初接手时该项目已经是一个半成品,建立了 20+ 个 app,且 app 间互相引用 model,各种外键。于是我决定重构项目,首先依业务逻辑的亲疏将 model 们重新分 app,然后定立了几条规矩:
- 不同 app 间禁止 import,更不许有外键
- 不同 app 间交互全部通过接口调用实现
- 一个 app 内的逻辑不关心外部需求,只通过发布/订阅模式进行异步通知
- 对于第三条不能满足的强事务需求,设计特殊的机制实现,但应尽量避免这种需求
最后 app 被紧缩为了 3 个。然后我又遇到了一个麻烦的问题:项目的目录布局如何设计。似乎我总是在这个问题上过于纠结,之前写一个 flask API 项目时也在这个问题上纠结了好几天(实际项目只写了三周)。最后在参阅了各种别人的实现后定义为下:(其实下表才是我这次博客的本来目的,一不小心多写了很多)
|——cms |——docs |——... |——cms |——apps |——app1 |——app2 |——... |——common |——lib |——settings |——base.py |——instance.py |——urls.py |——wsgi.py |——.git |——fabfile.py |——manage.py |——REAMME.rst |——requirements.txt
基本的想法就是:
- 不希望目录太深
- 最外层需要一个管理目录,业务代码放在第二层
- settings 需要支持分环境可配,但又不想搞很多什么 dev.py, local.py, production.py 这样的文件。我觉得就分为一个 base,放环境无关的配置,和 instance,放环境相关的配置就可以了。instance.py 文件则在部署时进行注入。
- Django 默认把管理 app(含 wsgi 的那个)和业务 app 放在一个目录下我感觉很别扭,所以单建了一个 apps 目录,所有 startapp 都指向这个目录。