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懶加載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM