Django settings file portion of source code analysis

Django settings file portion of source code analysis

In the process of writing Django project, which is a very powerful feature we can configure a number of options in the settings file to complete our work as expected, and these configurations also must be capitalized, otherwise it will not work. In addition, there is a set of Django itself more detailed configuration, Django how it is done the user to configure the configuration on the user's configuration, otherwise it uses its own default configuration. with this question, the user to view the configuration items related to source parts.

Process Analysis

First start Django project, usually by Django are python manage.py runserverstarting phrase command. From this entry function, mainly carried out the following three sentences.

if __name__ == "__main__":
    # settings文件配置到环境变量
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "auth_learn.settings")
    from django.core.management import execute_from_command_line
    # 解析并执行命令行参数
    execute_from_command_line(sys.argv)

We will be above the user's configuration file (settings file in the project) to set inside the current environment variables.

Follow the code flow down.

def execute_from_command_line(argv=None):
    """
    运行了一个命令管理工具, 将命令行的参数传到这个对象中, 并执行
    """
    utility = ManagementUtility(argv)
    utility.execute()

Continue to run down

def execute(self):
    # 解析命令行参数列表的第一个参数
    subcommand = self.argv[1]
    parser = CommandParser(None, usage="%(prog)s subcommand [options] [args]", add_help=False)
    options, args = parser.parse_known_args(self.argv[2:])
    handle_default_options(options)
    ...

    try:
        # 这句话就是重点了, 开始加载app
        settings.INSTALLED_APPS
    except ImproperlyConfigured as exc:
        self.settings_exception = exc

    ...

See this, finally I saw the files and settings related code. With the inside.

settings = LazySettings()

See settings is a lazy loading (loading delay) LazySettings instance of an object class.

Continue to follow up the definition of LazySettings

class LazySettings(LazyObject):
    def _setup(self, name=None):
        settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
        self._wrapped = Settings(settings_module)
   def __getattr__(self, name):
        if self._wrapped is empty:
            self._setup(name)
        val = getattr(self._wrapped, name)
        self.__dict__[name] = val  # 用到了直接缓存到__dict__里面
        return val
    ...

Found LazySettings class inherits from LazyObject, itself is not __init__a method, it continues to follow the parent class

 _wrapped = None
 def __init__(self):
    self._wrapped = empty

What parent does not define, it is an empty object, so the object initialization settings after what attributes does not, at this time Django calls settings.INSTALLED_APPSthis sentence is the core of lazy loading of so-called lazy loading, is the need to use when re-loading. General means there is a proxy class, thread ... Django used LazyObjectproxy class. Load function is a _setupfunction, when the property will go to get loaded.

LazySettingsInherited from LazyObjectclass, it overrides __getattr__and __setattr__methods, then the call settings.INSTALLED_APPSwhen triggers __getattr__this method under the double. We know that the initialization time, settings object is a empty empty object. This will load the function to call the _setupfunction

ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
def _setup(self, name=None):
    settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
    self._wrapped = Settings(settings_module)

First sentence, setting_module is access to our user-defined configuration file from the environment variable, which has just started manage.py file has been defined. Then go to Settings instantiate an object. This can be drawn from the Conclusion settingsobject's properties are from _wrappedacquiring the private property, or the instance of the object is obtained from Settings in the past.

Continue to follow up Source Settings category.

# global_settings就是一个django内部的全局配置文件
from django.conf import global_settings
class Settings(object):
    def __init__(self, settings_module):
        # 这句话就是遍历全局配置, 将所有的属性添加到settings对象中
        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)
        self._explicit_settings = set()
        # 遍历用户自定义配置文件
        for setting in dir(mod):
            # 如果我们配置的属性不是大写, 就会无效
            if setting.isupper():
                # 获取用户的配置属性
                setting_value = getattr(mod, setting)
                # 将我们配置的属性添加到settings配置文件中, 或者覆盖掉
                # Django默认的配置属性.
                setattr(self, setting, setting_value)
                self._explicit_settings.add(setting)

To this, the beginning of the problem will be solved. To sentence summary is that Django to load your own configuration file, and then load the user's profile to override default attributes, save settings to a delay loaded object. Configuration Cause file uppercase only because the source code only deals with property in all uppercase only.

reference

  1. http://www.hongweipeng.com/index.php/archives/1370/

  2. https://blog.csdn.net/qq_24551305/article/details/96486835

Guess you like

Origin www.cnblogs.com/yscl/p/11614807.html