Paolo
Paolo

Reputation: 21136

Namespaces issue in settings.py

I'm trying to customize how applications gets integrated in a generic Django project. The question is about how applications setting files can be imported into the project settings.py, so to keep app specific settings well separated from Django's. For example:

settings.py

# Django configuration settings...
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'cms'
}
# a bunch of other settings

# apps overridings and new settings
from settings_myapp import *

settings_myapp.py

from settings import DATABASES

DATABASES['cms'] = {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': 'cms'
}

So far so good. At runtime in Django settings the DATABASE dictionary reflects the changes the application did. But what if the app wants to add a new name into the outer namespace? Adding NEW_SETTING = True in myapp_settings and a couple of print statements at the end of settings.py, I get this:

$ python settings.py 
{'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': 'default'}}
Traceback (most recent call last):
  File "settings.py", line 8, in <module>
    from settings_myapp import *
  File "~/settings_myapp.py", line 1, in <module>
    from settings import DATABASES
  File "~/settings.py", line 10, in <module>
    print NEW_SETTING
NameError: name 'NEW_SETTING' is not defined

How do I avoid the circular import and get the thing done?

I think I'm lacking some basic Python concept here, I gave the Django context anyway because I'd also appreciate different solutions to hit the splitted settings target.

Upvotes: 0

Views: 380

Answers (1)

agf
agf

Reputation: 176960

This is one of those cases where execfile('settings_myapp.py') in the main settings file might actually be a good idea, since what you actually want to do is run some code in the current context.

Just take out the import from settings_myapp.py and it should work fine.

Edit: wanted to add that execfile() has been removed from Python 3; use exec(open(fn).read()).

Upvotes: 1

Related Questions