Django中settings配置文件源码分析
一:使用
在django中使用配置文件:
# 建议从conf中导入配置文件 而非直接导入该项目的配置文件 from django.conf import settings
二:源码分析
conf中的配置文件涵盖django的所有配置参数,项目的配置文件是给用户进行配置的。导入conf中的settings,在使用相关配置参数时会先去用户配置的settings中进行查找,找不到再去conf中的setting找,详情见如下源码分析:
# 生成LazyObject一个对象 初始化属性self._wrapped = empty settings = LazySettings() # 当settings使用点号查找属性时 会响应到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 #调用_setup(self, name=要查找的属性) 方法 将要查找的属性传入 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文件取出来 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)) #实例化Setting类,将用户的配置传入 self._wrapped = Settings(settings_module) #Setting的__init__方法 def __init__(self, settings_module): # update this dict from global settings (but only for ALL_CAPS settings) # global_settings就是django conf文件中的配置文件 dir()方法生成一个列表,其中的参数时该配置文件的所有变量名 for setting in dir(global_settings): if setting.isupper(): # 使用setattr为对象设值 setattr(self, setting, getattr(global_settings, setting)) # store the settings module in case someone later cares self.SETTINGS_MODULE = settings_module # import_module方法 拿到用户配置settings.py这个文件 mod = importlib.import_module(self.SETTINGS_MODULE) tuple_settings = ( "INSTALLED_APPS", "TEMPLATE_DIRS", "LOCALE_PATHS", ) self._explicit_settings = set() # 循环用户配置文件 如果和conf中配置文件的key相同那么就会覆盖原先设值的值。for循环完成,setting对象设值完成,里面包含用户的配置参数和conf中的配置参数 for setting in dir(mod): if setting.isupper(): setting_value = getattr(mod, setting) if (setting in tuple_settings and not isinstance(setting_value, (list, tuple))): raise ImproperlyConfigured("The %s setting must be a list or a tuple. " % setting) setattr(self, setting, setting_value) self._explicit_settings.add(setting)