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而不是自己编写脚本.