2

At the end of my settings.py file, I have:

try:
    from local_settings import *
except ImportError:
    pass

I then have a local_settings.py file where I have some db settings, etc. In this file I would also like to do the following (in order to use django_debug_toolbar):

INTERNAL_IPS = ('127.0.0.1',)
MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
INSTALLED_APPS += ('debug_toolbar',)

I want to put these settings here so that they don't show up in the production environment, which uses the main settings.py file, but of course this file can't access the original settings because it doesn't know about settings.py. How can I avoid a potentially circular import to achieve what I'm trying to do?

Anthony Mastrean
  • 21,850
  • 21
  • 110
  • 188
Jamie Forrest
  • 10,895
  • 6
  • 51
  • 68

2 Answers2

3

You can't do this. The imported module is executed in it's own scope and has no way of knowing where (and if) it is has been imported in any way. An alternative way would be something like this:

In your local_settings:

INTERNAL_IPS = ('127.0.0.1',)
MIDDLEWARE_CLASSES = ('debug_toolbar.middleware.DebugToolbarMiddleware',)
INSTALLED_APPS = ('debug_toolbar',)

And in the main settings.py

try:
    import local_settings as local
    has_local = True
except ImportError:
    has_local = False

# ...
if has_local:
    MIDDLEWARE_CLASSES += local.MIDDLEWARE_CLASSES
Martin Thurau
  • 7,564
  • 7
  • 43
  • 80
  • I like the idea, but the problem is that this scopes any settings in local_settings.py to local.* So anything that needs to access these settings will break. (E.g., I am using South for migrations, which uses the `DATABASE['Default']['Engine']` to set its db adapter. If I set things up as you say, I get the following error when I run the server: `There is no South database module 'south.db.None' for your database. Please either choose a supported database, check for SOUTH_DATABASE_ADAPTER[S] settings, or remove South from INSTALLED_APPS.` That's because it can't find the DATABASES setting. – Jamie Forrest Nov 22 '11 at 00:20
3

I use an approach in which my settings is actually a package and not a module

settings/ init.py base.py local.py #this one is on .gitignore

init.py:

from setings import *
try:
    from local.py import *
except ImportError:
    pass

base.py:

import os
DEBUG = False
TEMPLATE_DEBUG = DEBUG

SITE_ROOT = os.path.join( os.path.dirname( os.path.realpath(__file__) ) ,'..' )

ADMINS = (
    # ('Your Name', 'your_email@example.com'),
)

MANAGERS = ADMINS

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': '',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
    }

etc...

local.py:

from settings import settings as PROJECT_DEFAULT

PREPEND_WWW = False
DEBUG = True
TEMPLATE_DEBUG = DEBUG

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_pyscopg2', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'somesecretname',                      # Or path to database file if using sqlite3.
        'USER': 'somesecretuser',                      # Not used with sqlite3.
        'PASSWORD': 'somesecretpassword',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}

INSTALLED_APPS += PROJECT_DEFAULT.INSTALLED_APPS + ('debug_toolbar',)

You can see an example of this in here

armonge
  • 3,108
  • 20
  • 36
  • This is a nice approach, but I need to maintain a settings.py file in my top directory because that's how the prod environment I'm running it in needs it to be set up. – Jamie Forrest Nov 23 '11 at 01:21
  • @JamieForrest what do you mean whith mantaining settings.py in your top directory? – armonge Nov 23 '11 at 04:02