On Dec 2, 4:28 pm, Kyle Fox <[EMAIL PROTECTED]> wrote:
> 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.
Then don't duplicate the settings files and perform the overrides from
the WSGI script file for that specific site (presuming you are talking
about mod_wsgi).
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
import mysite.settings
mysite.settings.SITE_ID = 35
mysite.settings.TEMPLATE_DIRS = ['/www/example.com/templates/']
mysite.settings.MEDIA_ROOT = '/www/example.com/media/'
import sys
sys.path.append('/usr/local/django')
sys.path.append('/usr/local/django/mysite')
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
At least eliminates one set of files.
Graham
> 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
-~----------~----~----~----~------~----~------~--~---