0

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 <noreply@otakupride.com>' % 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 <noreply@otakupride.com>' % 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?

Jiaaro
  • 74,485
  • 42
  • 169
  • 190

2 Answers2

3

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

def get_dynamic_settings(context_dict):
    context_dict['DEFAULT_FROM_EMAIL'] = '%s <noreply@otakupride.com>' % 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']),)
Cat Plus Plus
  • 125,936
  • 27
  • 200
  • 224
  • 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 Oct 31 '09 at 20:57
  • 5
    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 Oct 31 '09 at 21:17
3

You might want to look into the various schemes people have used to configure many django sites without duplication: How to manage local vs production settings in Django? and Elegantly handle site-specific settings/configuration in svn/hg/git/etc?

Community
  • 1
  • 1
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • 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 Oct 31 '09 at 20:59