How to import a Django project settings.py Python file from a sub-directory?


Question

I created a sub-directory of my Django project called bin where I want to put all command-line run Python scripts. Some of these scripts need to import my Django project settings.py file that is in a parent directory of bin.

How can I import the settings.py file from a sub-directory of the project?

The code that I use in my command-line script to set into the "Django context" of the project is:

from django.core.management import setup_environ
import settings
setup_environ(settings)

This works fine if the script is in the root directory of my project.

I tried the following two hacks to import the settings.py file and then setup the project:

import os
os.chdir("..")

import sys
sys.path = [str(sys.path[0]) + "/../"] + sys.path

The cruel hack can import settings.py, but then I get the error:

project_module = __import__(project_name, {}, {}, [''])
ValueError: Empty module name
1
17
4/12/2010 6:24:01 PM

Accepted Answer

This is going one level up from your question, but probably the best solution here is to implement your scripts as custom manage.py (django-admin.py) commands. This gives you all of Django's functionality (including settings) for free with no ugly path-hacking, as well as command-line niceties like options parsing. I've never seen a good reason to write Django-related command-line scripts any other way.

10
3/7/2009 8:38:00 PM

I think your approach may be over-complicating something that Django 1.x provides for you. As long as your project is in your python path, you can set the environment variable DJANGO_SETTINGS_MODULE at the top of your script like so:

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

In your command line script where you need to read your settings, simply import the settings module from 'django.conf' as you would do in your application code:

from django.conf import settings

And presto, you have your settings and a Django-enabled environment for your script.

I personally prefer to set my DJANGO_SETTINGS_MODULE using '/usr/bin/env' in a bash script called 'proj_env' so I don't have to repeat it

#!/bin/bash

proj_env="DJANGO_SETTINGS_MODULE=myproject.settings"

/usr/bin/env $proj_env ${*}

With this, now I can run any python script with my Django application in context:

proj_env python -m 'myproject.bin.myscript'

If you use virtualenv, this also gives you a good place to source the activate script.

etc. etc.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon