• Django源码学习——配置文件解析



    同步发表在个人站点:https://panzhixiang.cn/2023/09/22/django-source-code-configuration/

    用Django好几年了,期间陆陆续续因为项目开发需要看过一点点源码,但是一直没有整体上看过源码,最近在B站上发现了一个不错的Django源码讲解教程,沈奇才·Django4.0源码解读,打算跟着这个视频过一遍,不过我看到的目前最新的代码,我从Django的官方仓库fork了一份代码,yexia553/django ,后面把想相关的注释和说明都提交在这个仓库的learning分支上。

    我不打算逐行解释代码,只会记录一些我觉得写的不错或者对我理解Django的设计有帮助的内容。

    这篇博客会记录一下django.conf.settings相关的代码,也就是Django中的项目配置相关的部分。

    global_settings

    这部分代码位于django.conf.global_settings,老实说,在这之前,我都不知道Django中还有这么一个代码的存在。

    django.conf.global_settings里面包含了相较于django.conf.settings更全面的配置项,也是django.conf.seetings的基础。

    settings

    Django的配置在代码中引用的时候如下:

    from django.conf import setting
    
    • 1

    实际代码位于django.conf.__init__.py这个文件里面

    下面是其中Settings类的一部分代码:

    class Settings:
        def __init__(self, settings_module):
            for setting in dir(global_settings):
                if setting.isupper():
                    setattr(self, setting, getattr(global_settings, setting))  # 这里用setattr动态设置属性
    
            self.SETTINGS_MODULE = settings_module
    
            # 动态地导入模块,于你在编写程序时并不知道具体会使用哪个模块,而是在运行时由用户输入或其他方式决定的情况非常有用。
            # 例如,在插件系统、基于配置的加载等场景中可能会用到它。
            mod = importlib.import_module(self.SETTINGS_MODULE)
    
            tuple_settings = (
                "ALLOWED_HOSTS",
                "INSTALLED_APPS",
                "TEMPLATE_DIRS",
                "LOCALE_PATHS",
                "SECRET_KEY_FALLBACKS",
            )
            self._explicit_settings = set()
            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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    主要关注里面的setattr(self, setting, getattr(global_settings, setting))mod = importlib.import_module(self.SETTINGS_MODULE)这两行代码。

    setattr(self, setting, getattr(global_settings, setting)) 通过setattr这个魔法函数来动态地为Settings类设置属性,这个设计使得我们可以在Django项目的settings.py这个文件中自定义配置并被django加载到。

    mod = importlib.import_module(self.SETTINGS_MODULE) 的作用是动态地(运行时)导入模块,这对于我们在编写程序时并不知道具体会使用哪个模块,而是在运行时由用户输入或其他方式决定的情况非常有用。
    其中的self.SETTINGS_MODULE 就是 DJANGO_SETTINGS_MODULE 这个环境变量的值,也正是因为这个设计,我们才可以把创建项目时默认的一个settings.py文件变成依据不同运行环境而编写的prod/settings.py、testing/settings.py等多个文件。
    想象一下,如果这里不使用动态引入,而是硬编码,我们就要为怎么适配不同的环境而头疼了。

  • 相关阅读:
    制作一个企业网站——html华为官网购物商城项目的设计与实现
    支持在线状态检查的仪表板miniboard
    一些关于完整小程序项目的优秀开源
    【Unity3D编辑器开发】Unity3D编辑器开发基础性框架结构【全面总结】
    整理MyBatis
    【测试理论基础之小程序/h5】
    【RHCE】web服务器及http配置(下)
    vue3写一个定时器
    面试不到10分钟就被赶出来了,问的实在是太变态了...
    VOC数据集介绍
  • 原文地址:https://blog.csdn.net/u013117791/article/details/133271460