前言
这段时间准备开始阅读和熟悉一下django的源码,达到更好地了解django项目,方便未来开发django 项目的目的。这是第一部分的阅读,阅读一些django项目启动时候相关的源码,针对django版本号2.2.5。
本次专题——django项目启动
我们都知道,启动一个django工程用的是python manage.py runserver命令,所以manage.py文件无疑就是启动django项目的入口文件,这里我将通过从入口文件出发,一步一步阅读跟django项目启动相关的源码,看看在这个过程中都做了些什么,同时给出我自己的解释。
本篇是第二部分,继续上一篇的内容,上一篇链接:
Normal WLS:Django项目启动——源码阅读(一)
注:源代码中两个井号"##"表示我自己的注解,是我认为需要重点分析或者是包含代码核心逻辑的地方,因为包含较多代码,所以建议在电脑端阅读。
源代码&分析
上一篇讲到了对于项目启动的runserver命令,真正关键的就是django.setup()函数,所以这里就从这个函数开始看起,来了解项目启动剩下的内容。
- django.setup()函数:django项目启动时真正执行的东西,其实也不复杂。
## django package: django/__init__.py
- apps.populate()函数:在项目启动时,对开发者写好的项目中的app进行配置。因为是类中的函数,用到了一些属性,所以这里把init函数也一起放出来。
## django package: django/apps/registry.py
- 上面代码中,有项目启动时候初始化django的各个app的代码,而各个app代码中存在针对各个app的配置,这些是由AppConfig类来做处理的,所以可以看到上面的代码中一直有调用http://app_config.xxx()函数,下面是三个比较主要的函数,为了更好地说明这个类,下面的代码中也把init函数放出来了:
- AppConfig.create()函数:所以,这个函数其实就是将我们自己生成的app的配置类xxxConfig进行实例化并返回,只是中间经过一系列路径解析和尝试import_module所以代码才这么长。
- AppConfig.import_models()函数:这里可以看到,import_models其实是从总的apps管理器对象那里去取自己对应的models存起来。这是因为如Apps类中所注释的:Every time a model is imported, ModelBase.__new__ calls apps.register_model which creates an entry in allmodels. 总的apps管理器会在import的时候注册所有的model,所以在注册某一个app配置实例(app_config)的时候,反而是app配置实例去apps管理器那里拿属于自己的models进行属性赋值。
- AppConfig.ready()函数:我们可以看到,ready函数是空的,是为了给开发者在需要在启动项目时候做一些一次性的事情留了一个接口,只需要在apps.py中重写ready函数就可以了,而且确实会在启动过程中执行。这个真的是看源码看出来的彩蛋了~
## django package: django/apps/config.py
总结
到这里,django项目启动部分配置相关的源码就算是分析完了,感觉还是很有收获的。
- 首先,我们了解了django项目的入口程序其实就是manage.py通过对命令行参数进行解析,然后对不同的命令进行不同的处理。
- 针对runserver(django项目启动),其实最最关键的地方就在于django/__init__.py中的setup函数,在这里先设置了url解析的前缀,让开发者既可以自定义,也可以在开发过程中的urls.py中不用添加前置'/',接下来就是对于所有app的相关配置。
- app的相关配置有两个关键部分,一个是对单个app的配置类AppConfig,一个是对所有app的管理类Apps,这两个类紧密相关,是总分关系,同时相互索引。在初始化过程中,Apps在控制流程,主要包括对所有app进行路径解析、名字去重、对每个app配置类进行初始化、赋予每个app配置类它们的相关models、还有就是执行每个app开发者自己定义的ready函数。
所以,看完源码,结合开发经验,我认为要想成功启动项目,最重要的就是把settings里面的installed_app变量写对,而且添加app之后记得把相对的路径加到配置文件中。同时,apps.py下的ready函数可以给我们一个不错的做启动的初始化的钩子,这个要记住并好好利用。