最近发现 Django settings 在使用的时候,容易出现不经过检查的问题。 因此,想要在 settings 的基础上严格约束一下,减少问题。
在进行相关技术调研的时候,发现了django-class-settings这个库。 实现方式很有意思,于是就调研了一下,学习到了很多新的东西。
这个库的核心思想,是在代码中,把一个类转换成一个 module; 这非常酷,让我们看看这是如何实现的。
按照代码的阅读思路,我们首先看看这个包的用法…
以下是README.md中的内容;
django-class-settings aims to simplify complicated settings layouts by using classes instead of modules. Some of the benefits of using classes include:
- Real inheritance
- [Foolproof settings layouts][local_settings]
- Properties
- Implicit environment variable names
Example
# .env
export DJANGO_SECRET_KEY='*2#fz@c0w5fe8f-'
export DJANGO_DEBUG=true
# manage.py
import os
import sys
import class_settings
from class_settings import env
from django.core.management import execute_from_command_line
if __name__ == '__main__':
env.read_env()
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
os.environ.setdefault('DJANGO_SETTINGS_CLASS', 'MySettings')
class_settings.setup()
execute_from_command_line(sys.argv)
# myproject/settings.py
from class_settings import Settings, env
class MySettings(Settings):
SECRET_KEY = env()
DEBUG = env.bool(default=False)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
ROOT_URLCONF = 'myproject.urls'
WSGI_APPLICATION = 'myproject.wsgi.application'
Installation
Install it from [PyPI][pypi-url] with [pip][pip-url]:
pip install django-class-settings
我们可以看到,这个类关键入口可能在env.read_env()
以及class_settings.setup()
。
我们首先看一下 src.class_settings.env
的代码。可以发现,这个代码用于加载 django 中的 env;
因此不是我们关注的重点。
让我们再看看关键函数 setup。
src/class_settings/__init__.py
:
__all__ = ["Env", "Settings", "env", "setup"]
__version__ = "0.3.0-dev"
from .env import Env, env
from .settings import Settings
def setup():
import sys
from django.conf import settings
from django.utils.functional import SimpleLazyObject
from .importers import SettingsImporter, LazySettingsModule
global _setup
if _setup:
return
sys.meta_path.append(SettingsImporter)
default_settings = LazySettingsModule()
settings_module = SimpleLazyObject(lambda: default_settings.SETTINGS_MODULE)
settings.configure(default_settings, SETTINGS_MODULE=settings_module)
_setup = True
_setup = False
在.settings.py
中没有直接加载的代码,因此,我们可以直接阅读本文件。
未完待续…