Search code examples
djangopython-module

How to set up DJANGO_SETTINGS_MODULE with absolute path of the settings.py file


I need to write some scripts for django and trying to set up the DJANGO_SETTINGS_MODULE environment variable at the beginning of each script. The scripts, manage.py and myproject directory are in the same parent directory. Additionally, settings.py file is in myproject directory.

Therefore, following code works correctly

#test_script_header.py

import os
os.environ["DJANGO_SETTINGS_MODULE"] = "myproject.settings"

import django
django.setup()

But following code doesn't work

#test_script_header.py

import os
os.environ["DJANGO_SETTINGS_MODULE"] = "/home/<username>/workspace/djangoapp/src/myproject/settings.py"

import django
django.setup()

I get the error

ModuleNotFoundError: No module named '/home/<username>/workspace/djangoapp/src/myproject/settings.py'

Here is the complete error message

Traceback (most recent call last):
  File "/home/<username>/workspace/djangoapp/src/test_script_header.py", line 22, in <module>
    django.setup()
  File "/usr/lib/python3/dist-packages/django/__init__.py", line 19, in setup
    configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
  File "/usr/lib/python3/dist-packages/django/conf/__init__.py", line 82, in __getattr__
    self._setup(name)
  File "/usr/lib/python3/dist-packages/django/conf/__init__.py", line 69, in _setup
    self._wrapped = Settings(settings_module)
  File "/usr/lib/python3/dist-packages/django/conf/__init__.py", line 170, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 992, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1004, in _find_and_load_unlocked
ModuleNotFoundError: No module named '/home/<username>/workspace/djangoapp/src/myproject/settings'

However, I want to eventually move all my django scripts to a myproject/scripts directory and execute them from there.

What am I doing wrong?


Solution

  • When you run this in a directory:

    python test_script_header.py

    The script’s directory is prepended to sys.path for you automatically. Due to this, if the directory is in the form:

    myproject
    |- test_script_header.py
    |- myproject
       |- settings.py

    You can correctly access the settings module using Python path syntax.

    os.environ["DJANGO_SETTINGS_MODULE"] = "myproject.settings"

    And Django can correctly locate that module and read all settings variables.

    But if the settings module is not in the script’s directory, you have to add the exact path of the directory it is in so that Python can correctly locate the module.

    For example, if the settings module is in the directory:

    /home/<username>/workspace/djangoapp/src/myproject/
    

    Prepend this directory to sys.path so that Python can locate the module correctly when you use Python path syntax.

    import sys
    import os
    import django
    
    sys.path.insert(0, "/home/<username>/workspace/djangoapp/src/myproject/")
    os.environ["DJANGO_SETTINGS_MODULE"] = "settings"
    django.setup()