21 Django之settings源码分析

482次阅读
没有评论

共计 2641 个字符,预计需要花费 7 分钟才能阅读完成。

引入

查看源码前提 :

  • 刚开始阅读一些库的源码的时候, 最好选一些代码量少的先感受一下
  • 碰到看不懂的, 我们没必要去死磕, 只看自己能看懂的, 看不懂的忽略

一.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)

21 Django 之 settings 源码分析

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 进入全局配置文件中查看配置

21 Django 之 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 类对象中所有的配置,
正文完
 
shawn
版权声明:本站原创文章,由 shawn 2023-06-16发表,共计2641字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)