Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

python

django

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
like image 686
MikeN Avatar asked Mar 06 '09 20:03

MikeN


People also ask

What is the base directory in Django?

BASE_DIR is your Django project directory. The same directory where manage.py is located.


2 Answers

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.

like image 119
Joe Holloway Avatar answered Oct 14 '22 14:10

Joe Holloway


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.

like image 43
Carl Meyer Avatar answered Oct 14 '22 14:10

Carl Meyer