Django 配置文件Settings源码分析

本文深入探讨了Django的配置文件Settings的源码,从导入方式开始,逐步解析了ENVIRONMENT_VARIABLE变量的含义,指出该值在manage.py中被设定。接着详细介绍了Settings的实例化过程,揭示了global_settings包含的默认配置,并阐述了importlib模块在其中的作用,帮助理解如何动态导入settings模块。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源码分析

1、导入settings文件的方式是

from django.conf import settings

2、点进settings文件中

# 发现settings是LazySettings的实例化对象
settings = LazySettings()

3、点击LazySettings到类的定义中

class LazySettings(LazyObject):
	def _setup(self, name=None):
		# os.environ 相当于是一个全局的字典,只要在项目当中通过os.environ都可以拿到这个字典,这里是从这个字典中取一个ENVIRONMENT_VARIABLE
       	settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
        if not settings_module:
     	... ...

4、点击ENVIRONMENT_VARIABLE进去看取得到底是什么值

ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"

看到这里得出是想从全局拿一个DJANGO_SETTINGS_MODULE的值,但是这个值在什么时候设置的呢,Django一旦启动肯定回查找settings文件,而Django的启动文件又是 manage.py,所以可以去 manage.py 中找找。

5、在 manage.py 中有这一句,相当于是字典的赋值,而这里的值就是项目中我们可以进行配置的settings文件的路径。

# 相当于 os.environ["DJANGO_SETTINGS_MODULE"] = "MyCode.settings"
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MyCode.settings")

6、拿到了这个值后回到第三步LazySettings类中,

def _setup(self, name=None):
    settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
    ... ...
    # 这里又实例化了一个对象,并且把拿到的settings_module传了进去,及"MyCode.settings"被传进去了
    self._wrapped = Settings(settings_module)

7、点进Settings中看上面对象的实例化过程

from django.conf import global_settings
... ...
class Settings(object):
    def __init__(self, settings_module):
        # 这里有一个global_settings,在最上面可以发现它的导入过程
        for setting in dir(global_settings):
            if setting.isupper():
		... ...

8、点进global_settings中可以发现,这个配置文件是Django系统默认的配置文件,所有的配置都在这里面。

from __future__ import unicode_literals
def gettext_noop(s):
    return s
####################
# CORE             #
####################
DEBUG = False
DEBUG_PROPAGATE_EXCEPTIONS = False
USE_ETAGS = False
... ...

9、回到第7步

def __init__(self, settings_module):
	# dir是获取当前对象里面所有的名称空间的名字,及拿到了配置文件中所有的变量名
    for setting in dir(global_settings):
    	# 判断循环到的变量名是不是大写
        if setting.isupper():
        	# setting, getattr(global_settings, setting)配置文件中的所有的变量名和对应的值
            setattr(self, setting, getattr(global_settings, setting))
    # 把前面获取到的字符串"MyCode.settings"赋值给SETTINGS_MODULE        
    self.SETTINGS_MODULE = settings_module
    # importlib.import_module将字符串变成from什么import什么,下面就变成了from MyCode import settings,及导入了项目中的配置文件
	mod = importlib.import_module(self.SETTINGS_MODULE)
	... ...
    # 拿到项目配置文件中变量名
    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)
                # 给对象设置属性,setting是项目的配置文件中的变量名,setting_value是项目的配置文件中的变量名对应的值,利用setattr如果变量在项目的配置文件中配置了就把对应的值赋给该变量,如果没有配置就使用系统的默认值
                setattr(self, setting, setting_value)
                self._explicit_settings.add(setting)

拓展:

importlib模块支持传入字符串来引入一个模块。importlib.import_module将字符串变成from什么import什么。

# 部分源码
def _find_and_load_unlocked(name, import_):
    path = None
    parent = name.rpartition('.')[0]
    ... ...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值