Django读取配置文件的机制解析

django.conf.init.py

class LazySettings(LazyObject):
    """
    A lazy proxy for either global Django settings or a custom settings object.
    The user can manually configure settings prior to using them. Otherwise,
    Django uses the settings module pointed to by DJANGO_SETTINGS_MODULE.
    """
    def _setup(self, name=None):
        """
        Load the settings module pointed to by the environment variable. This
        is used the first time we need any settings at all, if the user has not
        previously configured the settings manually.
        """ 通过指定的环境变量load设置模块
        settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
        if not settings_module:
            desc = ("setting %s" % name) if name else "settings"
            raise ImproperlyConfigured(
                "Requested %s, but settings are not configured. "
                "You must either define the environment variable %s "
                "or call settings.configure() before accessing settings."
                % (desc, ENVIRONMENT_VARIABLE))

        self._wrapped = Settings(settings_module) #这里是_wrapped的初始化 _wraped带有了各种global_settings里的属性
        .....
        .....
        def __getattr__(self, name):
        """
        Return the value of a setting and cache it in self.__dict__.
        """
        if self._wrapped is empty:
            self._setup(name)
        val = getattr(self._wrapped, name)  #返回从global_settings里得到的的属性
        self.__dict__[name] = val
        return val

__getattr__函数作用详解
首先要了解__getattr__函数的作用:
通过实例访问属性,都会经过__getattribute__函数。而当属性不存在时,仍然需要访问__getattribute__,不过接着要访问__getattr__。这就好像是一个异常处理函数。
当使用***类***访问不存在的变量是,不会经过__getattr__函数

这里的关键在于,如果我们的配置文件有定义一个CACHE的变量,我们又想在setting是个类的情况下直接使用setting.CACHE直接得到这个值,事实上Django不会在LazySettings及其所有父类中涉及到变量的初始化,但我们可以通过__getattr__函数的机制来得到这个值,通过import global_setting.py文件,在Setting这个类中实现了配置的初始化

from django.conf import global_settings
class Settings(object):
    def __init__(self, settings_module):
        # update this dict from global settings (but only for ALL_CAPS settings)
        for setting in dir(global_settings):
            if setting.isupper():
                setattr(self, setting, getattr(global_settings, setting))             #这里读取global_settings
                
        # store the settings module in case someone later cares
        self.SETTINGS_MODULE = settings_module                          

        mod = importlib.import_module(self.SETTINGS_MODULE)   #这里读取mysite.settings
		...
		...

而DJANGO_SETTING_MODULE环境变量是让django项目主文件夹下的settings模块被包含到python可以找到的目录下,开发情况下不需要(一般来说项目叫mysite,那么这个值就是mysite.settings)你可以在managy.py中找到:

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

我们通常会在当前文件夹运行,python可以搜索到。如果需要运行在其他服务器上,就必须指定DJANGO_SETTINGS_MODULE变量。
django在编译时,先载入global_settings.py中的配置,然后加载指定的settings文件,重写改变的设定。
Django – settings 详解

如果想写基于Django的软件想配置自己工程特有的设置的话,可以继承一个子类,在子类中重写一个_setup方法,同时赋值自己的环境变量和global_settings.py文件

猜你喜欢

转载自blog.csdn.net/kekefen01/article/details/83042068