下面,我们只看看主要的步骤:

1.项目启动,遍历settings下面的INSTALLED_APPS,导入默认配置。

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
'app02.apps.App02Config',
'niubin.apps.NiubinConfig',
]

2.接下来执行apps.populate(settings.INSTALLED_APPS)函数,该函数主要完成了以下几个步骤:

  step-one:

# 步骤一:初始化app配置并且导入app模块
for entry in installed_apps:
if isinstance(entry, AppConfig):
app_config = entry
else:
app_config = AppConfig.create(entry)
if app_config.label in self.app_configs:
raise ImproperlyConfigured(
"Application labels aren't unique, "
"duplicates: %s" % app_config.label) self.app_configs[app_config.label] = app_config
app_config.apps = self

  step-two:

 # 步骤二:导入model模块
for app_config in self.app_configs.values():
app_config.import_models()

  step-three:

# 步骤三:执行每个app模块中的ready()方法
for app_config in self.get_app_configs():
#app_config:<AuthConfig: auth>
#app_config:<SessionsConfig: sessions>
app_config.ready()# 这里要注意,如何apps中没有定义ready()方法,就会执行AppConfig类中的默认ready()方法

3.如果上述过程中的ready()函数执行了autodiscover()函数,如:autodiscover('nb'),就会完成以下操作:

def autodiscover_modules(*args, **kwargs):
'''搜索每个app下面的'admin'''
# args:'amdmin'
from django.apps import apps
register_to = kwargs.get('register_to')
for app_config in apps.get_app_configs():
# app_config:<AuthConfig: auth>....
for module_to_search in args:
# module_to_search:'admin'
# module_to_search:'niubi' 搜索每个app下的nb模块
pass

 這个函数完成的主要功能就是,搜索每个app下面的nb模块。也就是说,如果autodiscover('admin'),就会寻找每个app下面的admin模块,我们都知道,admin模块主要完成model的注册功能,那么只要调用了自动发现函数,那么函数的注册功能就在这一步完成的!

4.我们顺着admin.site.register()函数继续往下分析,这步操作完成了以下操作:

site = AdminSite() # 生成了一个全局的site实例

  接着,该实例调用了register函数,我们跟进去看看,這个函数做了什么操作:

    def register(self, model_or_iterable, admin_class=None, **options):
if not admin_class:
admin_class = ModelAdmin
if isinstance(model_or_iterable, ModelBase):
model_or_iterable = [model_or_iterable]
for model in model_or_iterable:
if model._meta.abstract:
raise ImproperlyConfigured(
'The model %s is abstract, so it cannot be registered with admin.' % model.__name__)
if model in self._registry:
raise AlreadyRegistered('The model %s is already registered' % model.__name__)
if not model._meta.swapped:
if options:
options['__module__'] = __name__
admin_class = type("%sAdmin" % model.__name__, (admin_class,), options)
self._registry[model] = admin_class(model, self)
 admin.site.register(models.UserGroup,admin.ModelAdmin)

  register操作完成以后,生成了一个这样的字典:

{
models.UserInfo: UserInfoAdmin(models.UserInfo,site对象)[add,change..],
models.UserGroup: ModelAdmin(models.UserGroup,site对象),}

  然后回到urls.py文件中,生成对应的路由映射关系:

urlpatterns = [
url(r'^nb/', v1.site.urls),
]

Django项目启动之前执行流程剖析的更多相关文章

  1. 开发必备知识点--django项目启动时,url加载之前,执行某个.py文件

    django项目启动时,自定义执行某个py文件 在任意的app下的apps.py中的Config类下自定义ready()方法,并且调用autodiscover_modules. app01/apps. ...

  2. Spring Security Oauth2 单点登录案例实现和执行流程剖析

    Spring Security Oauth2 OAuth是一个关于授权的开放网络标准,在全世界得到的广泛的应用,目前是2.0的版本.OAuth2在“客户端”与“服务提供商”之间,设置了一个授权层(au ...

  3. Springboot 项目启动后执行某些自定义代码

    Springboot 项目启动后执行某些自定义代码 Springboot给我们提供了两种"开机启动"某些方法的方式:ApplicationRunner和CommandLineRun ...

  4. Jedis cluster命令执行流程剖析

    Jedis cluster命令执行流程剖析 在Redis Cluster集群模式下,由于key分布在各个节点上,会造成无法直接实现mget.sInter等功能.因此,无论我们使用什么客户端来操作Red ...

  5. 在web项目启动时执行某个方法

    在web项目中有很多时候需要在项目启动时就执行一些方法,而且只需要执行一次,比如:加载解析自定义的配置文件.初始化数据库信息等等,在项目启动时就直接执行一些方法,可以减少很多繁琐的操作. 在工作中遇到 ...

  6. SpringMVC启动和执行流程

    Spring框架大家用得很多,相当熟悉,但是我对里面的运作比较好奇,例如bean的加载和使用,和我们定义的配置文件有什么联系;又例如aop在什么时候起作用,原理又是怎样.经过一个了解后,整理了启动和执 ...

  7. Django 中 admin 的执行流程

    Django 中 admin 的执行流程 1 循环加载执行所有已经注册的 app 中的 admin.py 文件 def autodiscover(): autodiscover_modules('ad ...

  8. Spring Security 案例实现和执行流程剖析

    Spring Security Spring Security 是 Spring 社区的一个顶级项目,也是 Spring Boot 官方推荐使用的安全框架.除了常规的认证(Authentication ...

  9. Spring Boot学习--项目启动时执行指定service的指定方法

    Springboot给我们提供了两种“开机启动”某些方法的方式:ApplicationRunner和CommandLineRunner. 这两种方法提供的目的是为了满足,在项目启动的时候立刻执行某些方 ...

随机推荐

  1. JS设计模式——10.门面模式

    门面模式 这是一种组织性的模式,它可以用来修改类和对象的接口,使其更便于使用.它可以让程序员过得更轻松,使他们的代码变得更容易管理. 门面模式有两个作用: 简化类的接口 消除与使用她的客户代码之间的耦 ...

  2. 【杂谈】需要mark的一些东西

    https://riteme.github.io/blog/2017-10-28/oi-coding-guidelines.html https://www.luogu.org/blog/34238/ ...

  3. os._exit(), sys.exit(), exit()

    1. sys.exit(n) 退出程序引发SystemExit异常, 可以捕获异常执行些清理工作. n默认值为0, 表示正常退出. 其他都是非正常退出. 还可以sys.exit("sorry ...

  4. LVS ARP广播产生的问题和处理方式【转】

    转自 LVS ARP广播产生的问题和处理方式-htckiller2010-ChinaUnix博客http://blog.chinaunix.net/uid-24960107-id-193084.htm ...

  5. 05 Diagnostics 诊断

    Diagnostics 诊断 Introduction 介绍 Profiling 分析 Tracing 跟踪 Debugging 调试 Runtime statistics and events 运行 ...

  6. Scrapy官网程序执行示例

    Windows 10家庭中文版本,Python 3.6.4,Scrapy 1.5.0, Scrapy已经安装很久了,前面也看了不少Scrapy的资料,自己尝试使其抓取微博的数据时,居然连登录页面(首页 ...

  7. Vue 实现countDown倒计时

    项目中要用到倒计时,用Vue 实现了一个 <template> <transition name="bkcd"> <div class="b ...

  8. 洛谷P1938 找工就业

    传送门啦 这个题本质就是跑一边最长路,重点就是在怎么建图上. 我们可以把点权放到边权上面,即将每一个边的终点点权当做这个边的边权,这个题里就是将工钱 $ d $ 当做边权. 如果这一条边需要坐飞机才能 ...

  9. 洛谷P3088 挤奶牛

    传送门啦 这个题也是一个单调队列来优化的 $ dp $ ,我们考虑这个题,这个题让我们求出有多少奶牛会觉得拥挤,如果我们还像琪露诺那个题那样单纯用一次单调队列肯定是不行的,因为牛觉不觉得拥挤是受左右的 ...

  10. jQuery对象与JS原生对象之间的转换

    1.将jQuery转换为dom对象的方法 [index] 或者.get(index): a.$(“#form”)[index] ,该方法获取form元素的dom对象 b.$(“#form”).get( ...