Django settings 源码分析
引入
查看源码前提 :
- 刚开始阅读一些库的源码的时候, 最好选一些代码量少的先感受一下
- 碰到看不懂的, 我们没必要去死磕, 只看自己能看懂的, 看不懂的忽略
一.django的两个配置文件
- 一个是暴露给用户可以自定义的配置文件 : 项目根目录下的setting.py文件
- 一个是项目默认的配置文件 : 当用户不做任何配置的时候自动加载默认配置
二.分析源码解决疑问
- 为什么配置文件必须是大写
- 为什么当前用户配置了就使用用户配置的, 不配置就使用默认的
三.源码分析
1.突破口 : settings 文件,将其导入
from django.conf import settings
2.Ctrl + 点击 settings 进入其中
......
settings = LazySettings()
发现它是由 LazySettings 类实例的对象
3.再点击进入到 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)
4.我们先点击 ENVIRONMENT_VARIABLE 进去看看这是个什么
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
翻译是Django的配置模板, Django在启动的时候就会加载这个配置, 我们再去Django的启动文件 manage.py 中去看看
5.进入 manage.py 文件查看相关内容
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
找到这一条, 将
'DJANGO_SETTINGS_MODULE':'mysite.settings'
添加进环境变量配置大字典中
6.返回到 LazySetting 类当中分析
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)
7.我们再点击进入 Settings 类中查看类代码
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))
......
8.点击 global_settings 进入全局配置文件中查看配置
"""
Default Django settings. Override these with settings in the module pointed to
by the DJANGO_SETTINGS_MODULE environment variable.
"""
# 默认的Django设置,用Django settings模块环境变量指向的模块中的设置覆盖这些设置
# 意思就是说这是默认的配置文件, 如果你在暴露给用户的settings文件中配置了某变量则覆盖这里面的变量
9.我们再返回 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://blog.taoxiaoxin.club/185.html
来源:淘小欣的博客
文章版权归作者所有,未经允许请勿转载。
THE END
0
二维码
海报
Django settings 源码分析
引入
查看源码前提 :
刚开始阅读一些库的源码的时候, 最好选一些代码量少的先感受一下
碰到看不懂的, 我们没必要去死磕, 只看自己能看懂的, 看不懂的忽略
一……

共有 0 条评论