先了解下官方文档的介绍

Django包含了一个已经安装应用的注册表,这个注册表存储着配置信息以及用来自省,同时也维护着可用模型的列表。

这个注册表就是apps,位于django.apps下,本质上是一个django.apps.registry模块下的一个Apps类的实例。

源码面前见真相:

  

class Apps(object):

  这是一个注册表,存储着已安装应用的配置信息,同时也跟踪着模型,例如提供reverse-relations。

初始化的主要属性:

  apps_configs:这是一个有顺序的字典,将AppConfig实例的label标签映射到已经安装的entry(AppConfig)上。

主要方法:

  populate(installded_app):载入应用的配置信息和模型,这个方法导入每个应用模块然后是每个模型模块,它是线程安全并且是幂等(任意多次执行所产生的影响均与一次执行的影响相同)的,但是不能重入(reentrant),简单百度下,应该是不能进行递归调用的意思。

  

 if self.ready:    #该注册表是否已经被填充
return # populate() might be called by two threads in parallel on servers
# that create threads before initializing the WSGI callable.
     # populate()在初始化WSGI调用之前,可能会被会创建线程的服务器上的两个并行的线程调用。
with self._lock:
     #_lock()为Theading.Lock()对象,在with上下文管理器中自动获取锁,处理过后,自动释放锁。
if self.ready:
return # app_config should be pristine, otherwise the code below won't
# guarantee that the order matches the order in INSTALLED_APPS.
       # app_config应该是处于原始的状态,否则下面的代码将不能保证这个顺序匹配INSTALLED_APPS中的顺序。
if self.app_configs:
raise RuntimeError("populate() isn't reentrant") # Phase 1: initialize app configs and import app modules.
for entry in installed_apps:
         # 迭代已安装apps的每一项
if isinstance(entry, AppConfig):
app_config = entry
else:
            # 若INSTALLED_APPS中配置的不是AppConfig类的Python路径而是App模块路径,将会以工厂方式进行创建。
app_config = AppConfig.create(entry)
if app_config.label in self.app_configs:
            # 检测app_config的唯一性。
raise ImproperlyConfigured(
"Application labels aren't unique, "
"duplicates: %s" % app_config.label) self.app_configs[app_config.label] = app_config # app_config.label属性默认是由app_name获取的。
app_config.apps = self #将注册表赋给AppConfig类的apps属性。 # Check for duplicate app names.
counts = Counter(
app_config.name for app_config in self.app_configs.values())
duplicates = [
name for name, count in counts.most_common() if count > 1]
if duplicates:
raise ImproperlyConfigured(
"Application names aren't unique, "
"duplicates: %s" % ", ".join(duplicates)) self.apps_ready = True # Phase 2: import models modules.
       # 导入模型模块
for app_config in self.app_configs.values():
app_config.import_models() self.clear_cache() self.models_ready = True # Phase 3: run ready() methods of app configs.
       # 运行apps configs的ready()方法。
for app_config in self.get_app_configs():
app_config.ready() self.ready = True

Django之Apps源码学习的更多相关文章

  1. Django之AppConfig源码学习

    class AppConfig(object) 这个基类描述了一个Django应用以及它的配置信息. 属性: name:django应用的完整python路径,eg.'django.contrib.a ...

  2. Django Rest Framework源码剖析(八)-----视图与路由

    一.简介 django rest framework 给我们带来了很多组件,除了认证.权限.序列化...其中一个重要组件就是视图,一般视图是和路由配合使用,这种方式给我们提供了更灵活的使用方法,对于使 ...

  3. Django如何启动源码分析

    Django如何启动源码分析 启动 我们启动Django是通过python manage.py runsever的命令 解决 这句话就是执行manage.py文件,并在命令行发送一个runsever字 ...

  4. Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结

    2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash--系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度.唯品会.58同城.新浪微博.趣分 ...

  5. jQuery源码学习感想

    还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码, ...

  6. MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)

    前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾. ...

  7. MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则)

    前言:上篇介绍了下自己的MVC框架前两个版本,经过两天的整理,版本三基本已经完成,今天还是发出来供大家参考和学习.虽然微软的Routing功能已经非常强大,完全没有必要再“重复造轮子”了,但博主还是觉 ...

  8. MVC系列——MVC源码学习:打造自己的MVC框架(二:附源码)

    前言:上篇介绍了下 MVC5 的核心原理,整篇文章比较偏理论,所以相对比较枯燥.今天就来根据上篇的理论一步一步进行实践,通过自己写的一个简易MVC框架逐步理解,相信通过这一篇的实践,你会对MVC有一个 ...

  9. MVC系列——MVC源码学习:打造自己的MVC框架(一:核心原理)

    前言:最近一段时间在学习MVC源码,说实话,研读源码真是一个痛苦的过程,好多晦涩的语法搞得人晕晕乎乎.这两天算是理解了一小部分,这里先记录下来,也给需要的园友一个参考,奈何博主技术有限,如有理解不妥之 ...

随机推荐

  1. java设计模式---备忘录模式

    一.引子 俗话说:世上难买后悔药.所以凡事讲究个"三思而后行",但总常见有人做"痛心疾首"状:当初我要是--.如果真的有<大话西游>中能时光倒流的& ...

  2. Java 多线程 死锁 隐性死锁 数据竞争 恶性数据竞争 错误解决深入分析 全方向举例

    在几乎所有编程语言中,由于多线程引发的错误都有着难以再现的特点,程序的死锁或其它多线程错误可能只在某些特殊的情形下才出现,或在不同的VM上运行同一个程序时错误表现不同.因此,在编写多线程程序时,事先认 ...

  3. React 之props属性

    React 里有一个非常常用的模式就是对组件做一层抽象.组件对外公开一个简单的属性(Props)来实现功能,但内部细节可能有非常复杂的实现. 可以使用 JSX 展开属性 来合并现有的 props 和其 ...

  4. DB 查询分析器 方便地创建DB2自定义函数

    DB 查询分析器 方便地创建DB2自定义函数                           马根峰            (广东联合电子服务股份有限公司, 广州 510300) 摘要       ...

  5. MinerBean.java 数据库表 miner bean

    MinerBean.java 数据库表 miner bean package com.iteye.injavawetrust.miner; import java.util.Date; /** * 数 ...

  6. [leetcode]经典算法题- String to Integer (atoi)

    题目描述: 把字符串转化为整数值 原文描述: Implement atoi to convert a string to an integer. Hint: Carefully consider al ...

  7. UML之结尾篇

    作为十期的孩子,我们已经开发过两个系统,学生管理系统和机房收费系统,也接触了软工,编写了一系列文档,不知道小朋友有没有这种感觉,开发一个系统软件和编写一个程序是不一样的,他们之间的差别,用一个比喻来说 ...

  8. 01_JNI是什么,为什么使用,怎么用JNI,Cygwin环境变量配置,NDK案例(使用Java调用C代码),javah命令使用

    1 什么是JNI JNI Java本地开发接口 JNI是一个协议,这个协议用来沟通java代码和外部的本地代码(C/C++) 通过这个协议,java代码就可以调用外部的C/C++代码,外部的C/C++ ...

  9. STL - list(双向链表)

    List简介 list是一个双向链表容器,可高效地进行插入删除元素. list不可以随机存取元素,所以不支持at.(pos)函数与[]操作符.It++(ok) it+5(err) #include & ...

  10. ANN实现

    ANN核心数据结构: typedef struct  {     int input_n;                  /* number of input units */     int h ...