这里有两种解决方案。你可以在应用程序中设置 settings.py
文件并填充默认值。
为单个应用程序配置默认值
在你的代码中使用 from MYAPP import settings
代替 from django.conf import settings
。
编辑 YOURAPP/__init__.py
:
from django.conf import settings as user_settings
from . import settings as default_settings
class AppSettings:
def __getattr__(self, name):
if hasattr(user_settings, name):
return getattr(user_settings, name)
if hasattr(default_settings, name):
return getattr(default_settings, name)
raise AttributeError("'Settings' object has no attribute '%s'" % name)
settings = AppSettings()
为整个项目配置默认值
在你的代码中使用from MYPROJECT import settings
,而不是from django.conf import settings
。
编辑MYPROJECT/MYPROJECT/__init__.py
import os, sys, importlib
from . import settings as user_settings
def get_local_apps():
"""Returns the locally installed apps names"""
apps = []
for app in user_settings.INSTALLED_APPS:
path = os.path.join(user_settings.BASE_DIR, app)
if os.path.exists(path) and app != __name__:
apps.append(sys.modules[app])
return apps
class AppSettings:
SETTINGS_MODULE = 'settings'
def __getattr__(self, setting_name):
if hasattr(user_settings, setting_name):
return getattr(user_settings, setting_name)
for app in get_local_apps():
module_source = os.path.join(app.__path__[0], "%s.py" % self.SETTINGS_MODULE)
module_binary = os.path.join(app.__path__[0], "%s.pyc" % self.SETTINGS_MODULE)
if os.path.exists(module_source) or os.path.exists(module_binary):
module = importlib.import_module("%s.%s" % (app.__name__, self.SETTINGS_MODULE))
if hasattr(module, setting_name):
return getattr(module, setting_name)
raise AttributeError("'Settings' object has no attribute '%s'" % setting_name)
settings = AppSettings()
这种解决方案看起来更容易安装,但不能保证返回良好的默认值。如果多个应用在它们的settings.py中声明同一变量,您无法确定哪个应用程序将返回您请求的默认值。
app_settings.py
之前导入项目的settings.py
文件吗? - Flimmmyapp_settings
,它将在第一个getattr
时初始化 Django 的 LazySettings,并给出配置错误(因为 此行 将返回部分评估的myapp_settings
模块 而我们正在评估它,而不是进入无限循环导入)。我还没有找到一个干净的解决方法。 - scry