physicalattraction
physicalattraction

Reputation: 6858

Wrong settings module in Django

I have made the following directory structure:

project
    main_app
        settings
            base.py
            local.py
            production.py
    ...
    manage.py

I started local.py with:

from .base import *

I update manage.py as follows (mentioned 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)

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:

from django.conf import settings

data_dir = Path(settings.BASE_DIR) / 'csv'

When I run this script however, I get the following error upon loading the object settings:

django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.

When I print the settings module in class Settings in django/conf/__init__.py, I see that it takes the wrong settings file (which does not exist):

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

Why doesn't it take the correct settings file, as indicated in manage.py? I read here that it might be a circular reference in middleware, but I can't find it. This is my middleware setting:

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',
]

When I echo the environment variable $DJANGO_SETTINGS_MODULE in a shell, I get an empty line back. To check if the environment variable is set somewhere in my project, I search for it explicitly in the terminal.

$ 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")

Upvotes: 2

Views: 2605

Answers (2)

Andrea Corbellini
Andrea Corbellini

Reputation: 17751

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:

How do you call your script? Clearly not via manage.py.

This line:

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings.local")

needs to appear in every script.

Also, be sure that there is nothing around that is overriding the value for DJANGO_SETTINGS_MODULE, and nothing that is manually calling settings.configure().


Tip: to avoid repeating the same code over and over again, and to avoid problems of this kind, I often use custom management commands instead of writing my own scripts.

Upvotes: 2

Dmitry Yudin
Dmitry Yudin

Reputation: 978

I dont know if it helps, but i will tell what i know and how we do this. First of all its a bad idea to patch manage.py. I believe this file need to be untouched. We have following setup: one settings.py contains settings and variables for project. Near it we have local.py. and in the settings we have: import * from local. this file lives on a local machine and have something like this:

#database settings for sqlite
#passwords for apis
debug=True

then we have to add this file to .gitignore so after git pull from production we wont be have this file on production server. On production we create another local.py

#database settings for production database
#passwords for apis
debug=False

So local is mean not development but "local for this machine"

Upvotes: 0

Related Questions