Reputation: 6858
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
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
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