from django.conf import settings
......
settings = LazySettings()
发现它是由 LazySettings 类实例的对象
class LazySettings(LazyObject):
def _setup(self, name=None):
# os.environ获取环境变量中所有的配置,相当于一个大字典,这里取出ENVIRONMENT_VARIABLE
settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
if not settings_module:
......
self._wrapped = Settings(settings_module)
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
翻译是Django的配置模板, Django在启动的时候就会加载这个配置, 我们再去Django的启动文件 manage.py 中去看看
os.environ.setdefault(‘DJANGO_SETTINGS_MODULE‘, ‘mysite.settings‘)
找到这一条, 将
‘DJANGO_SETTINGS_MODULE‘:‘mysite.settings‘
添加进环境变量配置大字典中
class LazySettings(LazyObject):
def _setup(self, name=None):
# 这里相当于是 settings_module = ‘mysite.settings‘
settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
......
# 这里是将settings_module,也就是‘mysite.settings‘传入到Settings类中实例化得到一个对象
self._wrapped = Settings(settings_module)
from django.conf import global_settings
class Settings:
def __init__(self, settings_module):
# update this dict from global settings (but only for ALL_CAPS settings)
# 上面的提示是从全局配置中更新此字典(仅针对所有大写的配置),那么我们可以知道global_setting是一个全局配置文件
for setting in dir(global_settings):
if setting.isupper():
setattr(self, setting, getattr(global_settings, setting))
......
"""
Default Django settings. Override these with settings in the module pointed to
by the DJANGO_SETTINGS_MODULE environment variable.
"""
# 默认的Django设置,用Django settings模块环境变量指向的模块中的设置覆盖这些设置
# 意思就是说这是默认的配置文件, 如果你在暴露给用户的settings文件中配置了某变量则覆盖这里面的变量
class Settings(object):
def __init__(self, settings_module): # ‘mysite.settings‘
# dir()获取全局配置文件里面所有的变量名,循环取出来
for setting in dir(global_settings):
if setting.isupper(): # 校验是否是纯大写(这也就是配置变量小写无效)
# getattr()获取全局变量中所有的大写配置的值
# setattr()再将该配置名以及对应的值添加到Settings对象中
setattr(self, setting, getattr(global_settings, setting))
# 将‘mysite.settings‘赋值给self.SETTINGS_MODULE后面使用
self.SETTINGS_MODULE = settings_module
# importlib模块:以字符串的方式导入模块,也就导入了暴露给用户的配置文件
# from mysite import settings
mod = importlib.import_module(self.SETTINGS_MODULE)
for setting in dir(mod):
if setting.isupper():
# 循环取出暴露给用户配置文件中的所有大写的配置值
setting_value = getattr(mod, setting)
.......
# 然后再将其设置进入Settings对象中,有就覆盖,没有就添加
setattr(self, setting, setting_value)
通过 Settings 类的源码分析, 我们可以得出这样一个步骤 :
- 先得到全局配置文件中所有的大写的配置, 并将其加入到 Settings类对象中去
- 然后再获取暴露给用户的 settings 配置中所有大写的值, 并将其也设置进 Settings 类对象中
- 这样一来 Settings 类对象中如果第一次添加的配置名与第二次添加的配置名相同, 就会被第二次的配置覆盖
- Django 启动加载的就是这个 Settings 类对象中所有的配置,
原文:https://www.cnblogs.com/songhaixing/p/14588907.html