Django 中错误的设置模块
Wrong settings module in Django
我做了如下目录结构:
project
main_app
settings
base.py
local.py
production.py
...
manage.py
我从 local.py
开始:
from .base import *
我更新manage.py
如下(提到here):
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.local")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
运行 我的单元测试有效。我 运行 本地服务器,可以正常工作。调用 API 有效。然后我调用一个脚本,其中包含以下内容:
from django.conf import settings
data_dir = Path(settings.BASE_DIR) / 'csv'
然而,当我 运行 这个脚本时,我在加载对象时收到以下错误 settings
:
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
当我在 class Settings in django/conf/__init__.py
中打印设置模块时,我看到它采用了错误的设置文件(不存在):
class Settings(BaseSettings):
...
print('Settings module: {}'.format(settings_module))
print('DJANGO_SETTINGS_MODULE: {}'.format(os.environ['DJANGO_SETTINGS_MODULE']))
Settings module: project.settings
DJANGO_SETTINGS_MODULE: project.settings
为什么它没有采用正确的设置文件,如 manage.py
中所示?我看here说可能是中间件中的循环引用,但是我找不到。这是我的中间件设置:
MIDDLEWARE_CLASSES = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
]
当我在 shell 中回显环境变量 $DJANGO_SETTINGS_MODULE
时,我得到一个空行。为了检查我的项目中是否设置了环境变量,我在终端中明确搜索它。
$ pwd
/Applications/XAMPP/htdocs/project/src
$ sift DJANGO_SETTINGS_MODULE
Binary file matches: project/__pycache__/wsgi.cpython-35.pyc
main_app/wsgi.py:os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main_app.settings.local")
Binary file matches: fe_import/__pycache__/CsvReader.cpython-35.pyc
fe_import/CsvReader.py: os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main_app.settings.local") ==> This is the script I am running
manage.py: os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main_app.settings.local")
我不知道它是否有帮助,但我会告诉您我所知道的以及我们如何做到这一点。首先,修补 manage.py 不是个好主意。我相信这个文件需要保持不变。我们有以下设置:一个 settings.py 包含项目的设置和变量。在它附近我们有 local.py。在设置中我们有:import * from local
。这个文件存在于本地机器上并且有这样的东西:
#database settings for sqlite
#passwords for apis
debug=True
然后我们必须将此文件添加到 .gitignore 以便在 git 从生产中拉出后我们将不会在生产服务器上拥有此文件。
在生产中我们创建另一个 local.py
#database settings for production database
#passwords for apis
debug=False
所以本地不是开发而是 "local for this machine"
Running my unit tests works. I run the server locally, which works. Making calls to the API works. I then call a script, in which I have the following:
你如何调用你的脚本?显然不是通过 manage.py
.
这一行:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.local")
需要出现在每个脚本中。
此外,请确保周围没有任何东西覆盖 DJANGO_SETTINGS_MODULE
的值,也没有任何东西手动调用 settings.configure()
.
提示:为了避免一遍又一遍重复相同的代码,为了避免出现此类问题,我经常使用custom management commands而不是自己编写脚本.
我做了如下目录结构:
project
main_app
settings
base.py
local.py
production.py
...
manage.py
我从 local.py
开始:
from .base import *
我更新manage.py
如下(提到here):
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.local")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
运行 我的单元测试有效。我 运行 本地服务器,可以正常工作。调用 API 有效。然后我调用一个脚本,其中包含以下内容:
from django.conf import settings
data_dir = Path(settings.BASE_DIR) / 'csv'
然而,当我 运行 这个脚本时,我在加载对象时收到以下错误 settings
:
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.
当我在 class Settings in django/conf/__init__.py
中打印设置模块时,我看到它采用了错误的设置文件(不存在):
class Settings(BaseSettings):
...
print('Settings module: {}'.format(settings_module))
print('DJANGO_SETTINGS_MODULE: {}'.format(os.environ['DJANGO_SETTINGS_MODULE']))
Settings module: project.settings
DJANGO_SETTINGS_MODULE: project.settings
为什么它没有采用正确的设置文件,如 manage.py
中所示?我看here说可能是中间件中的循环引用,但是我找不到。这是我的中间件设置:
MIDDLEWARE_CLASSES = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
]
当我在 shell 中回显环境变量 $DJANGO_SETTINGS_MODULE
时,我得到一个空行。为了检查我的项目中是否设置了环境变量,我在终端中明确搜索它。
$ pwd
/Applications/XAMPP/htdocs/project/src
$ sift DJANGO_SETTINGS_MODULE
Binary file matches: project/__pycache__/wsgi.cpython-35.pyc
main_app/wsgi.py:os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main_app.settings.local")
Binary file matches: fe_import/__pycache__/CsvReader.cpython-35.pyc
fe_import/CsvReader.py: os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main_app.settings.local") ==> This is the script I am running
manage.py: os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main_app.settings.local")
我不知道它是否有帮助,但我会告诉您我所知道的以及我们如何做到这一点。首先,修补 manage.py 不是个好主意。我相信这个文件需要保持不变。我们有以下设置:一个 settings.py 包含项目的设置和变量。在它附近我们有 local.py。在设置中我们有:import * from local
。这个文件存在于本地机器上并且有这样的东西:
#database settings for sqlite
#passwords for apis
debug=True
然后我们必须将此文件添加到 .gitignore 以便在 git 从生产中拉出后我们将不会在生产服务器上拥有此文件。 在生产中我们创建另一个 local.py
#database settings for production database
#passwords for apis
debug=False
所以本地不是开发而是 "local for this machine"
Running my unit tests works. I run the server locally, which works. Making calls to the API works. I then call a script, in which I have the following:
你如何调用你的脚本?显然不是通过 manage.py
.
这一行:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.local")
需要出现在每个脚本中。
此外,请确保周围没有任何东西覆盖 DJANGO_SETTINGS_MODULE
的值,也没有任何东西手动调用 settings.configure()
.
提示:为了避免一遍又一遍重复相同的代码,为了避免出现此类问题,我经常使用custom management commands而不是自己编写脚本.