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 val2)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)文章
解決python腳本中error: unrecognized arguments: True錯(cuò)誤
這篇文章主要介紹了解決python腳本中error: unrecognized arguments: True錯(cuò)誤,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
python淺析守護(hù)線程與非守護(hù)線程的區(qū)別與使用
守護(hù)線程,又稱后臺線程,它是在后臺運(yùn)行的,如果所有前臺線程都死亡,那么后臺線程就會自動死亡,本章我們來了解守護(hù)線程與非守護(hù)線程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-08-08
Python自動提取項(xiàng)目中導(dǎo)入的庫及其版本信息
在我們有時(shí)需要遷移或部署項(xiàng)目時(shí),需要知道項(xiàng)目所依賴的三方包和版本,本文就來介紹一下Python自動提取項(xiàng)目中導(dǎo)入的庫及其版本信息,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
有關(guān)wxpython pyqt內(nèi)存占用問題分析
一直覺得wxpython占用內(nèi)存比較多,在工作中寫的一些小程序應(yīng)用,一對比其它的小程序,發(fā)現(xiàn)內(nèi)存相差確實(shí)有點(diǎn)大2014-06-06
基于python實(shí)現(xiàn)地址和經(jīng)緯度轉(zhuǎn)換
這篇文章主要介紹了基于python實(shí)現(xiàn)地址和經(jīng)緯度轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05

