在拆分 Django 设置文件时临时修改 `builtins`

Temporarily modifying `builtins` while splitting a django settings file

我正在启动一个 django 1.10 项目,想要拆分设置文件。我对任何现有解决方案都不满意。

  1. 我不希望能够覆盖另一个文件中的 string/boolean/dict 设置。每个 string/boolean/dict 设置只能在一处设置。这使得跟踪定义事物的位置变得容易。
  2. 我不想手动扩展 tuple/list 设置,例如INSTALLED_APPS += (test_app)。这似乎很混乱,需要我跟踪另一个文件中是否使用了列表或元组。

  3. 我不想在多个文件中 import os 和定义 BASE_DIR。干.

我看了很多其他的解决方案,将 settings.py 替换为包含 local_settings.pycommon_settings.py__init__.py.

的目录

__init__.py中,我import os计算BASE_DIR。然后我

import builtins
builtins.BASE_DIR = BASE_DIR
builtins.os = os

from .common_settings import *
from . import local_settings

# At this point both modules have run and we no longer need to be messing
# with the builtins namespace.
del builtins.BASE_DIR
del builtins.os
del builtins

然后我循环 dir(local_settings) 并弄乱 globals() 来实现前两个要求(如果需要,我可以 post 整个事情,但我对我的使用感兴趣builtins)。

这个builtins的用法是不是太邪恶了?有什么可以打破它。显然,如果任一标识符与更高版本的 builtins 的属性冲突,那么此代码将破坏 python。如果使用这些标识符中的任何一个的函数最终出现在其中一个设置文件中并且稍后被调用,那么它就会中断。

不过我没有看到其中任何一个发生。是否存在我没​​有发现的潜在问题?

以这种方式修改 builtins 的主要问题是它无缘无故地向您的代码添加了非本地推理。 common/local 设置模块的行为现在隐含地取决于导入它们的模块中发生的事情。太糟糕了。

基本上,您需要摆脱要求 #3。

  • 在每个模块中导入 os 不是 "repeating yourself",因为每个模块都将 os 导入到自己的命名空间中。这就是 Python 的工作原理。

  • 你只想定义一次 BASE_DIR 是对的,但正确的方法是在一个模块中定义变量(比如 basedir.py)和然后将该变量 (from basedir import BASE_DIR) 显式导入到使用它的每个模块中。