指定配置文件
django通过DJANGO_SETTINGS_MODULE环境变量指定要加载的配置文件。
通过startproject命令新建项目后,在生成的manage.py文件中,即自动设置了DJANGO_SETTINGS_MODULE变量值为项目下的settings文件。
# 新建项目
django-admin startproject myproject
# manage.py
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
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?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
可以通过修改DJANGO_SETTINGS_MODULE指定配置文件。如下
# manange.py文件中
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myconf.settings')
在代码中使用配置
在代码中使用配置,通过如下方式引入
from django.conf import settings
if settings.DEBUG:
# Do something
注意 django.conf.settings 并不是一个模块!-- 而是一个对象!所以引入某个单独的设置项是不对的。
from django.conf.settings import DEBUG # This won't work.
lazyObject解析
配置文件加载的代码位于django/conf目录。主要逻辑在__init____.py文件中。
# django/conf/__init__.py
# settings是一个对象,通过LazySettings类初始化实例
settings = LazySettings()
# 具体加载逻辑,通过Settings类进行初始化
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
class LazySettings(LazyObject):
def _setup(self, name=None):
settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
self._wrapped = Settings(settings_module)
加载的逻辑没有太多复杂的地方,主要解析下django的懒加载类LazyObject。
用到了比较多的魔法函数。
# django/utils/functional.py
empty = object()
def new_method_proxy(func):
def inner(self, *args):
if (_wrapped := self._wrapped) is empty:
self._setup()
_wrapped = self._wrapped
return func(_wrapped, *args)
inner._mask_wrapped = False
return inner
class LazyObject:
_wrapped = None
# 初始化为empty
def __init__(self):
self._wrapped = empty
# 属性访问的魔法函数,settings.debug
def __getattribute__(self, name):
def __setattr__(self, name, value):
def __delattr__(self, name):
# 浅拷贝和深拷贝的魔法函数
def __copy__(self):
def __deepcopy__(self, memo):
# 容器访问的魔法函数,settings['debug']
__getitem__ = new_method_proxy(operator.getitem)
__setitem__ = new_method_proxy(operator.setitem)
__delitem__ = new_method_proxy(operator.delitem)
# 其他魔法函数
__iter__ = new_method_proxy(iter)
__len__ = new_method_proxy(len)

954

被折叠的 条评论
为什么被折叠?



