views:

94

answers:

2

Here is my situation...

I am trying to dynamically generate a bunch of stuff in my settings.py file on a django site.

I am setting up several sites, (via sites framework) and I want to have some values I plug in to a function that will generate a portion of the settings file for each site.

for example:

from universal_settings import *

SITE_NAME = 'First Site'
SITE_SLUG = 'firstsite'

DEFAULT_FROM_EMAIL = '%s <[email protected]>' % SITE_NAME
ROOT_URLCONF = 'mysite.urls.%s' % SITE_SLUG
TEMPLATE_DIRS += ( os.path.join(PROJECT_ROOT, "templates", SITE_SLUG), )

obviously it's a huge violation of DRY to have those last 3 lines in the settings file for every site running this code. So I want to do something like this

from universal_settings import *
from utils import get_dynamic_settings

SITE_NAME = 'First Site'
SITE_SLUG = 'firstsite'

get_dynamic_settings( locals() )

And here is the function

# WARNING: THIS CODE DOES NOT WORK!
def get_dynamic_settings(context_dict):
    global DEFAULT_FROM_EMAIL
    global ROOT_URLCONF
    global TEMPLATE_DIRS

    DEFAULT_FROM_EMAIL = '%s <[email protected]>' % context_dict['SITE_NAME']
    ROOT_URLCONF = 'mysite.urls.%s' % context_dict['SITE_SLUG']
    TEMPLATE_DIRS += ( os.path.join(PROJECT_ROOT, "templates", context_dict['SITE_SLUG']), )

so my question is... how do I add things to the scope of the settings file? it doesn't seem to have a dict object available to the variables within it.

Maybe I'm going about this all wrong? Thanks for your help!

PS - my understanding of the global keyword is that it tells the compiler that the function means to manipulate a global variable within it's own file - is there such a thing for the file which the function is called?

+3  A: 

Dict returned by locals() (or globals()) is mutable, so you could do:

def get_dynamic_settings(context_dict):
    context_dict['DEFAULT_FROM_EMAIL'] = '%s <[email protected]>' % context_dict['SITE_NAME']
    context_dict['ROOT_URLCONF'] = 'mysite.urls.%s' % context_dict['SITE_SLUG']
    context_dict['TEMPLATE_DIRS'] += (os.path.join(PROJECT_ROOT, "templates", context_dict['SITE_SLUG']),)
PiotrLegnica
I was thinking about that, but I was trying to use setattr on it... I guess that was my folley. Thanks this is much nicer than what I was trying to do :)
Jiaaro
Actually, the docs for locals() say: "Warning: The contents of this dictionary should not be modified; changes may not affect the values of local variables used by the interpreter."
Ned Batchelder
+3  A: 

You might want to look into the various schemes people have used to configure many django sites without duplication: http://stackoverflow.com/questions/1626326/how-to-manage-local-vs-production-settings-in-django and http://stackoverflow.com/questions/1406892/elegantly-handle-site-specific-settings-configuration-in-svn-hg-git-etc

Ned Batchelder
I've actually got a pretty nice method of managing the difference between boxes - I just wanted to programically apply a group of settings to each settings file using simple string concatenation
Jiaaro