最近发现 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 1
2
3
# .env
export DJANGO_SECRET_KEY = '*2#fz@c0w5fe8f-'
export DJANGO_DEBUG = true
Copy 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 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 )
Copy 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 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'
Copy Installation Install it from [PyPI][pypi-url] with [pip][pip-url]:
1
pip install django-class-settings
Copy 我们可以看到,这个类关键入口可能在env.read_env()
以及class_settings.setup()
。
我们首先看一下 src.class_settings.env
的代码。可以发现,这个代码用于加载 django 中的 env;
因此不是我们关注的重点。
让我们再看看关键函数 setup。
src/class_settings/__init__.py
:
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
__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
Copy 在.settings.py
中没有直接加载的代码,因此,我们可以直接阅读本文件。
未完待续…