Django加載配置的過(guò)程詳解
一. Django服務(wù)啟動(dòng) 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í)候才會(huì)去計(jì)算。Django提供了兩種惰性加載模塊,分別是lazy和LazyObject,前者主要針對(duì)可以調(diào)用的對(duì)象,延遲函數(shù)的調(diào)用;后者針對(duì)類(lèi),延遲類(lèi)的實(shí)例化。
如果想要讓某個(gè)類(lèi)有延遲實(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沒(méi)有INSTALLED_APPS屬性就會(huì)調(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的類(lèi)屬性)為T(mén)rue, 就會(huì)執(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) 后面再訪問(wèn)屬性時(shí)直接從self._wrapped.dict(settings.wrapped.dict)中獲取
到此這篇關(guān)于Django加載配置的過(guò)程詳解的文章就介紹到這了,更多相關(guān)django加載配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決python腳本中error: unrecognized arguments: True錯(cuò)誤
這篇文章主要介紹了解決python腳本中error: unrecognized arguments: True錯(cuò)誤,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
python淺析守護(hù)線(xiàn)程與非守護(hù)線(xiàn)程的區(qū)別與使用
守護(hù)線(xiàn)程,又稱(chēng)后臺(tái)線(xiàn)程,它是在后臺(tái)運(yùn)行的,如果所有前臺(tái)線(xiàn)程都死亡,那么后臺(tái)線(xiàn)程就會(huì)自動(dòng)死亡,本章我們來(lái)了解守護(hù)線(xiàn)程與非守護(hù)線(xiàn)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-08-08
Python自動(dòng)提取項(xiàng)目中導(dǎo)入的庫(kù)及其版本信息
在我們有時(shí)需要遷移或部署項(xiàng)目時(shí),需要知道項(xiàng)目所依賴(lài)的三方包和版本,本文就來(lái)介紹一下Python自動(dòng)提取項(xiàng)目中導(dǎo)入的庫(kù)及其版本信息,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03
有關(guān)wxpython pyqt內(nèi)存占用問(wèn)題分析
一直覺(jué)得wxpython占用內(nèi)存比較多,在工作中寫(xiě)的一些小程序應(yīng)用,一對(duì)比其它的小程序,發(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)換,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05

