Django加載配置的過程詳解
一. Django服務(wù)啟動 manage.py
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ui.settings") 設(shè)置配置文件環(huán)境變量-
#!/usr/bin/env python import os import sys if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ui.settings") try: from django.core.management import execute_from_command_line except ImportError: # The above import may fail for some other reason. Ensure that the # issue is really that Django is missing to avoid masking other # exceptions on Python 2. try: import django except ImportError: raise ImportError( "Couldn't import Django. Are you sure it's installed and " "available on your PYTHONPATH environment variable? Did you " "forget to activate a virtual environment?" ) raise execute_from_command_line(sys.argv)
二. 引入配置
django/core/management/init.py文件中引入配置
from django.conf import settings
django/conf/init.py配置文件源碼
from django.utils.functional import LazyObject, empty ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE" 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. """ 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) def __repr__(self): # Hardcode the class name as otherwise it yields 'Settings'. if self._wrapped is empty: return '<LazySettings [Unevaluated]>' return '<LazySettings "%(settings_module)s">' % { 'settings_module': self._wrapped.SETTINGS_MODULE, } 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) self.__dict__[name] = val return val def __setattr__(self, name, value): """ Set the value of setting. Clear all cached values if _wrapped changes (@override_settings does this) or clear single values when set. """ if name == '_wrapped': self.__dict__.clear() else: self.__dict__.pop(name, None) super(LazySettings, self).__setattr__(name, value) def __delattr__(self, name): """ Delete a setting and clear it from cache if needed. """ super(LazySettings, self).__delattr__(name) self.__dict__.pop(name, None) def configure(self, default_settings=global_settings, **options): """ Called to manually configure the settings. The 'default_settings' parameter sets where to retrieve any unspecified values from (its argument must support attribute access (__getattr__)). """ if self._wrapped is not empty: raise RuntimeError('Settings already configured.') holder = UserSettingsHolder(default_settings) for name, value in options.items(): setattr(holder, name, value) self._wrapped = holder @property def configured(self): """ Returns True if the settings have already been configured. """ return self._wrapped is not empty settings = LazySettings() # 單例模式
LazySettings()惰性加載是一種延遲計(jì)算的技術(shù),當(dāng)只有真正需要使用結(jié)果的時(shí)候才會去計(jì)算。Django提供了兩種惰性加載模塊,分別是lazy和LazyObject,前者主要針對可以調(diào)用的對象,延遲函數(shù)的調(diào)用;后者針對類,延遲類的實(shí)例化。
如果想要讓某個(gè)類有延遲實(shí)例化的功能,必須做兩件事情:
1)繼承LazyObject;
2)實(shí)現(xiàn)_setup方法。
empty = object() def new_method_proxy(func): def inner(self, *args): if self._wrapped is empty: self._setup() return func(self._wrapped, *args) return inner class LazyObject(object): """ A wrapper for another class that can be used to delay instantiation of the wrapped class. By subclassing, you have the opportunity to intercept and alter the instantiation. If you don't need to do that, use SimpleLazyObject. """ # Avoid infinite recursion when tracing __init__ (#19456). _wrapped = None def __init__(self): """ 初始化 """ # Note: if a subclass overrides __init__(), it will likely need to # override __copy__() and __deepcopy__() as well. self._wrapped = empty __getattr__ = new_method_proxy(getattr) def __setattr__(self, name, value): if name == "_wrapped": # Assign to __dict__ to avoid infinite __setattr__ loops. self.__dict__["_wrapped"] = value else: if self._wrapped is empty: self._setup() setattr(self._wrapped, name, value) def __delattr__(self, name): if name == "_wrapped": raise TypeError("can't delete _wrapped.") if self._wrapped is empty: self._setup() delattr(self._wrapped, name) def _setup(self): """ Must be implemented by subclasses to initialize the wrapped object. """ raise NotImplementedError('subclasses of LazyObject must provide a _setup() method') def __reduce__(self): if self._wrapped is empty: self._setup() return (unpickle_lazyobject, (self._wrapped,)) def __getstate__(self): if self._wrapped is empty: self._setup() return self._wrapped.__dict__
三. 加載配置
ManagementUtility 的execute方法的 settings.INSTALLED_APPS
1) settings.INSTALLED_APPS 因?yàn)閟ettings沒有INSTALLED_APPS屬性就會調(diào)用LazySettings的__getattr__方法
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) self.__dict__[name] = val return val
2)self._wrapped is empty(empty是LazyObject的類屬性)為True, 就會執(zhí)行LazySettings的_setup方法,實(shí)例self._wrapped =Settings(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. """ 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)
3) 后面再訪問屬性時(shí)直接從self._wrapped.dict(settings.wrapped.dict)中獲取
到此這篇關(guān)于Django加載配置的過程詳解的文章就介紹到這了,更多相關(guān)django加載配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Pycharm運(yùn)行時(shí)總是跳出Python?Console問題
這篇文章主要介紹了Pycharm運(yùn)行時(shí)總是跳出Python?Console問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04Python Paramiko實(shí)現(xiàn)SSHv2協(xié)議輕松管理遠(yuǎn)程服務(wù)器
這篇文章主要為大家介紹了Python Paramiko實(shí)現(xiàn)SSHv2協(xié)議輕松管理遠(yuǎn)程服務(wù)器,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01Mac中Python 3環(huán)境下安裝scrapy的方法教程
作為一名python爬蟲愛好者,怎能不折騰下Scrapy?折騰了許久之后終于安裝到了mac中,所以下面這篇文章主要給大家介紹了關(guān)于Mac系統(tǒng)中Python 3環(huán)境下安裝scrapy的相關(guān)資料,文中將實(shí)現(xiàn)的步驟一步步介紹的非常詳細(xì),需要的朋友可以參考下。2017-10-10Python+OpenCV數(shù)字圖像處理之ROI區(qū)域的提取
ROI區(qū)域又叫感興趣區(qū)域。在機(jī)器視覺、圖像處理中,從被處理的圖像以方框、圓、橢圓、不規(guī)則多邊形等方式勾勒出需要處理的區(qū)域,稱為感興趣區(qū)域,ROI。本文主要為大家介紹如何通過Python+OpenCV提取ROI區(qū)域,需要的朋友可以了解一下2021-12-12Keras 利用sklearn的ROC-AUC建立評價(jià)函數(shù)詳解
這篇文章主要介紹了Keras 利用sklearn的ROC-AUC建立評價(jià)函數(shù)詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06python數(shù)據(jù)結(jié)構(gòu)算法分析
這篇文章主要介紹了python數(shù)據(jù)結(jié)構(gòu)算法分析,在python的數(shù)據(jù)結(jié)構(gòu)的章節(jié)中,我們上次學(xué)習(xí)到了python面向?qū)ο蟮乃枷?,即我們想用程序來?shí)現(xiàn)一個(gè)東西,我們需是用對象的特征來描述我們想構(gòu)建的對象。感興趣的小伙伴可以查看下面內(nèi)容</P><P>2021-12-12python庫JsonSchema驗(yàn)證JSON數(shù)據(jù)結(jié)構(gòu)使用詳解
這篇文章主要為大家介紹了python庫JsonSchema驗(yàn)證JSON數(shù)據(jù)結(jié)構(gòu)的使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05