Django源码笔记——settings加载

settings对象

通常要获取settings的配置项时候都会通过from django.conf import settings获取。

settings是一个LazySettings实例对象,在django.conf的__init__.py下settings = LazySettings(),由于模块本身只执行一次所以这是一个单例(简单说就是你每次导入的settings都是同一个实例对象)

参考:python单例

class LazySettings(LazyObject)

class LazySettings(LazyObject):
    def _setup(self, name=None):
        # 根据配置的settings文件导入配置
        settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
        pass
        self._wrapped = Settings(settings_module)     # 和下面的UserSettingsHolder一样都是BaseSettings子类

    def __getattr__(self, name):
        # 获取属性时候没有导入配置则导入
        if self._wrapped is empty:
            self._setup(name)
        return getattr(self._wrapped, name)

    def configure(self, default_settings=global_settings, **options):
        # 手动自定义配置,没有配置才能使用
        if self._wrapped is not empty:
            raise RuntimeError('Settings already configured.')
        holder = UserSettingsHolder(default_settings)    # 和上面的Settings一样都是BaseSettings子类
        for name, value in options.items():
            setattr(holder, name, value)
        self._wrapped = holder            

    @property
    def configured(self):
        return self._wrapped is not empty

父类LazyObject中很多类似__getattr__ = new_method_proxy(getattr)的使用,没有配置时候先导入配置 ,然后获取self._wrapped配置中的信息和属性

相当于:__getattr__ = getattr(self,_wrapped, *args)

def new_method_proxy(func):
    def inner(self, *args):
        if self._wrapped is empty:
            self._setup()
        return func(self._wrapped, *args)
    return inner

测试

In [7]: dir(settings)
Out[7]:
['ABSOLUTE_URL_OVERRIDES',
 'ADMINS',
 'ALLOWED_HOSTS',
 'ALLOWED_INCLUDE_ROOTS',
# 省略...

总结:LazySettings主要用于控制配置文件的来源

class Settings

实际上配置文件的配置都在Settings中, 配置文件中的配置(必须全部大写)都添加为Settings实例的属性。UserSettingsHolder中配置都在LazySettings中手动循环添加,这里不在赘述,下面只看Settings导入配置过程

class BaseSettings(object):
    """
    Common logic for settings whether set by a module or by the user.
    """
    def __setattr__(self, name, value):
        # "MEDIA_URL", "STATIC_URL"两项配置必须以"/"结尾
        if name in ("MEDIA_URL", "STATIC_URL") and value and not value.endswith('/'):
            raise ImproperlyConfigured("If set, %s must end with a slash" % name)
        object.__setattr__(self, name, value)

class Settings(BaseSettings):
    def __init__(self, settings_module):
        # 配置项必须为全大写
        for setting in dir(global_settings):    # 导入默认配置文件的配置,即初始化配置
            if setting.isupper():
                setattr(self, setting, getattr(global_settings, setting))

        # store the settings module in case someone later cares
        self.SETTINGS_MODULE = settings_module
        mod = importlib.import_module(self.SETTINGS_MODULE)        # import指定的配置文件
        self._explicit_settings = set()
        for setting in dir(mod):        # 导入配置指定配置文件中的配置项覆盖默认配置
            if setting.isupper():
                setting_value = getattr(mod, setting)
                pass
                setattr(self, setting, setting_value)
                self._explicit_settings.add(setting)
            pass
    


    def is_overridden(self, setting):
        return setting in self._explicit_settings

现在settings中已经有所有的配置项

conf包

|- conf
|--- app_template            # app目录模板:manage.py startapp
|--- locale                        # 语言包和对应时间表示格式
|--- project_template        # app项目模板 :manage.py startproject
|--- urls

转载于:https://my.oschina.net/watcher/blog/823346

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值