zoukankan      html  css  js  c++  java
  • Django settings加载

    使用

    应从django模块引入配置:

    from django.conf import settings
    

    而不是直接从项目文件中引入

    from proj import settings
    

    直接从项目文件中引入会破坏app的独立性。比如我想要把proj项目中的支付模块pay_app分离出去,就要修改所有pay_app中直接从proj项目配置文件中引入配置的语句

    注意,django.conf.settings不是一个模块,而是一个对象。 所以不可以单独导入每个配置项:

    from django.conf.settings import DEBUG  # 这是错误的做法
    

    指定配置文件

    在Django启动时需要制定配置文件,也就是给环境变量DJANGO_SETTINGS_MODULE赋值

    # 万物起源:manage.py
    #!/usr/bin/env python
    import os
    import sys
    
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "demo.settings")
    

    LazySettings

    from django.conf import settings
    

    实际上是引入了LazySettings类的一个实例,这是一个单例模式,每次导入的settings都是同一个实例对象

    # django/conf/__init__.py
    class LazySettings(LazyObject):
        ...
    
    settings = LazySettings()
    

    LazySettings继承自LazyObject,它会以懒加载的机制去读取配置,获取某个属性的当下才会去加载

    ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
    
    
    class LazySettings(LazyObject):
        def _setup(self, name=None):
            # 从环境变量DJANGO_SETTINGS_MODULE中获取配置文件位置
            settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
            # 真正读取配置的对象是Settings的实例
            self._wrapped = Settings(settings_module)
    
        def __getattr__(self, name):
            # 实例化settings后,settings被访问前,settings._wrapped为空对象
            if self._wrapped is empty:
                # 访问settings的属性,即调用__getattr__时才回去加载配置
                self._setup(name)
            val = getattr(self._wrapped, name)
            # 访问对象的属性时会先在 __dict__ 中查找
            # 没有找到,才会去调用 __getattr__ 方法
            # 因此这里使用self.__dict__做了缓存
            self.__dict__[name] = val
            return val
    
    
    empty = object()
    
    class LazyObject(object):
        _wrapped = None
    
        def __init__(self):
            self._wrapped = empty
    

    LazySettingss主要用于控制配置文件的来源,并实现了懒加载的机制,真正读取配置的对象是Settings的实例

    Settings

    from django.conf import global_settings
    
    class Settings(object):
        def __init__(self, settings_module):
            # global_settings 中是Django的默认配置
            for setting in dir(global_settings):
                if setting.isupper():
                    # 先加载Django的默认配置
                    setattr(self, setting, getattr(global_settings, setting))
    
            self.SETTINGS_MODULE = settings_module
            # 载入项目配置
            mod = importlib.import_module(self.SETTINGS_MODULE)
    
            for setting in dir(mod):
                # 只会载入项目配置文件中全部大写的 KEY
                # 因此,如果选择用django.conf导入配置,配置的KEY必须要全部大写
                # 如果直接从配置文件导入就没有这个限制了
                if setting.isupper():
                    setting_value = getattr(mod, setting)
                    # 项目配置会覆盖Django的默认配置
                    # 相当于 self.__dict__[setting] = setting_value
                    setattr(self, setting, setting_value)
    

    参考资料

    配置 Django

    Django源码笔记——settings加载

    Django源码分析(七):settings懒加载

  • 相关阅读:
    编译原理:算符优先分析
    编译原理:自下而上语法分析
    编译原理:实验二 递归下降语法分析
    编译原理:LL(1)文法的判断,递归下降分析程序
    作业9 DFA最小化
    作业8 非确定的自动机NFA确定化为DFA
    作业7 正规式到正规文法与自动机
    作业6 正规文法与正规式
    作业5 词法分析程序的设计与实现
    作业4 文法和语言总结与梳理
  • 原文地址:https://www.cnblogs.com/luozx207/p/13209826.html
Copyright © 2011-2022 走看看