ソースコード解析のDjangoの設定ファイル部分
我々は予想通り、私たちの仕事を完了するために、設定ファイルにオプションの数を設定することができ、これらの構成も大文字にする必要があり、それ以外の場合は動作しません非常に強力な機能ですDjangoプロジェクトを、書く。またの過程では、Djangoの自身のセットがありますそれ以外の場合は元の部品に関連する設定項目を表示するために独自のデフォルト設定。この質問で、ユーザーを使用して、ユーザーの設定に設定を構成するには、ユーザーがどのように行われるか、より詳細な構成、ジャンゴ。
プロセス分析
まずされ、通常はジャンゴで、Djangoのプロジェクトを開始しpython manage.py runserver
、フレーズコマンドを開始する。このエントリ関数から、主に以下の三つの文章を行いました。
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)
私たちは、現在の環境変数内に設定する(設定は、プロジェクト内のファイル)は、ユーザーの設定ファイルの上になります。
ダウンコードの流れに従ってください。
def execute_from_command_line(argv=None):
"""
运行了一个命令管理工具, 将命令行的参数传到这个对象中, 并执行
"""
utility = ManagementUtility(argv)
utility.execute()
ダウンを実行し続けます
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
...
これを参照してください、最終的に私は、コードを関連するファイルと設定を見ました。内部で。
settings = LazySettings()
設定を参照して、オブジェクト・クラスの遅延ロード(装填遅延)LazySettingsインスタンスです。
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
...
発見LazySettingsクラスは、LazyObjectから自分自身を継承しない__init__
方法、それは親クラスに従うことを続けます
_wrapped = None
def __init__(self):
self._wrapped = empty
どのような属性は、この時点でDjangoは呼び出していません後にどのような親が定義されていません、それは空のオブジェクトなので、オブジェクトの初期化設定settings.INSTALLED_APPS
この文は、再読み込みを使用する必要性、いわゆる遅延読み込みの遅延ロードの中核となっている。一般的なプロキシクラス、スレッドがあることを意味... Djangoは使用LazyObject
プロキシクラスを。ロード機能がある_setup
プロパティがロードされますに行きます機能、。
LazySettings
継承されLazyObject
たクラス、それが優先されます__getattr__
と__setattr__
呼び出し、その後、方法settings.INSTALLED_APPS
トリガすると__getattr__
、二重の下で、この方法を。我々は、初期化時には、設定がオブジェクト空の空のオブジェクトであること。これが呼び出す関数をロードします知っている_setup
機能を
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
def _setup(self, name=None):
settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
self._wrapped = Settings(settings_module)
最初の文、setting_moduleはちょうどmanage.pyファイルを開始した環境変数から、私たちのユーザー定義の構成ファイルへのアクセスである[設定]に進みます。定義されているこれはから引き出すことができるオブジェクトをインスタンス化します。結論settings
オブジェクトのプロパティからある_wrapped
私有財産の取得、またはオブジェクトのインスタンスは、過去の設定から取得されます。
ソース設定カテゴリをフォローアップし続けます。
# 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)
このために、問題の始まりは解決されます。要約を宣告するためにDjangoは独自の構成ファイルをロードして、デフォルトの属性を上書きするために、ユーザーのプロファイルをロードし、遅延ロードされたオブジェクトに設定を保存することです。設定ソースコードのみが唯一、すべて大文字でプロパティを扱うためだけ大文字のファイルを引き起こします。
参照