I needed a way to alter settings at runtime, based on the current Site. The method I came up with appears to work, but certainly doesn't feel elegant and (I'm sure) could use improvement. I'm going to share my reasoning behind dynamic settings in the hopes that it sparks some discussion about how this could best be achieved, and possibly included, with Django. At the very least I hope for feedback from more experienced Python veterans :)
-- The Why -- Our internal CMS uses the Sites framework to relate all content to a particular client website. All clients share the same database and most of the same settings. An example of a client's settings file looks like this: from cms.conf.global_settings import * SITE_ID = 35 TEMPLATE_DIRS = ['/www/example.com/templates/'] MEDIA_ROOT = '/www/example.com/media/' This setup requires a Python settings file, a WSGI config file and an Apache Virtual Host for each Site, which is silly because the *only* difference between sites is the three settings above. Multiple static files have worked satisfactory thus far, but becomes a maintenance problem as the number of sites increase. Furthermore, it doesn't seem very DRY because most of the configuration gets duplicated for each Site. In order to eliminate the need for a settings file for each site, I began investigating using middleware to detect the current Site (based on request.get_host()) and dynamically alter SITE_ID, MEDIA_ROOT and TEMPLATE_DIRS. I need to set SITE_ID because the rest of our CMS uses the CurrentSiteManager to perform lookups (which behind the scenes uses settings.SITE_ID). -- My interim solution -- My approach was partly inspired by a Django snippet[1] and partly by Threaded Multihost[2], a component that Satchmo uses to support multiple Sites. Here's a quick paste of the code: http://dpaste.com/hold/95266/ Again, I know it's ugly and needs massive improvement (by someone smarter than me). But here's how it works: 1) Middleware looks up the current Site based on domain, and sets two variables, "request" and "site", on the thread. 2) The ThreadSetting class provides a descriptor to use in your settings files to mark settings that may be altered at runtime. This lets you do things like provide a function that gets called to determine the value for a given setting at any point in execution. The descriptor allows this to happen without breaking the "settings.FOO" syntax. Callbacks get passed _thread_locals (which will include the "request" and "site" from middleware). Lastly, LazySetting's getattr/setattr is monkey-patched to allow access to these descriptors. 3) In settings.py you use ThreadSetting to specify which settings can be altered, along with the function that should be used to calculate the setting value whenever it's requested. You can see in my example how it's used to set SITE_ID and TEMPLATE_DIRS. As far as I can tell, in order to use the Sites framework to build a [near] zero configuration application *without* breaking CurrentSiteManager or Site.objects.get_current(), settings.SITE_ID will need to be set at runtime based on the request's hostname. Additionally, this needs to be done in such a way that multiple threads are not simultaneously modifying the same setting (thus the use of thread locals). I expect using the Sites framework to create "instant-on" domains and subdomains from a single Django application is a common use-case, especially for hosted web applications. It would be *awesome* if Django somehow accommodated this use-case. I'm very interested in hearing other's thoughts on the subject. I would love a way to do this in a Django-approved fashion, without having to monkey-patch LazySettings. Thanks, Kyle. [1] http://www.djangosnippets.org/snippets/1099/ [2] http://gosatchmo.com/apps/django-threaded-multihost/ --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-developers?hl=en -~----------~----~----~----~------~----~------~--~---