If all you need to change is the SITE_ID on the settings file, using
different files for each is not only a mess to handle, but also means
that you'll spend extra RAM for each instance running.

I solve this by using a middleware that changes the SITE_ID based on
the request's hostname:

SITES_DICT = 'cached-sites-dict'

class MultiHostMiddleware(object):
    def process_request(self, request):
        if cache.has_key(SITES_DICT):
            sites = cache.get(SITES_DICT)
        else:
            sites = {}
            for site in Site.objects.all():
                sites[site.domain.lower()] = {
                    'id': site.id,
                }
            cache.set(SITES_DICT, sites)

        try:
            host = request.META["HTTP_HOST"].lower().replace('www.',
'')
            domain = urlparse(host).path
            settings.SITE_ID = sites[domain]['id']
        except KeyError:
            raise Http404()

This way I only have one instance running 'hundreds' of websites.
With this approach you can create a OneToOne model SiteOptions to
store extra settings, like TEMPLATE_DIRS, STATIC_ROOT, or other site's
options like API keys and such. I have an app that has the fields for
the site I'm doing but it works fine.

If you need different urlconfs, you could also do it in the middleware
(since urls are resolved against request.urlconf which you can set
there), but I think that at that point you're talking about another
website so I'd use a different settings file for it.


On Jan 27, 3:16 pm, Graham Dumpleton <[email protected]>
wrote:
> On Friday, January 28, 2011 2:09:06 AM UTC+11, Tom Evans wrote:
>
> > On Wed, Jan 26, 2011 at 6:18 PM, Jari Pennanen <[email protected]>
> > wrote:
> > > On Jan 26, 6:56 pm, FeatherDark <[email protected]> wrote:
> > >> Greetings huge django developer list,
> > >> I just wanted to mention, this method totally works for me, I call it
> > >> "Skinning"
>
> > >> In the templates folder I have a file called "base.html'
> > >> Inside that file is only 1 line:
> > >> {% extends request.META.HTTP_HOST|cut:':'|add:'.html'%}
>
> > > request.META.HTTP_HOST is coming from Client. "Trust but verify", you
> > > are not verifying this. It could pose a security risk. One could send
> > > a request with malicious Host header and make the site retrieve
> > > different template. This is not a serious issue, since you probably
> > > don't have templates that would wreak havoc.
>
> > > Why don't you create own template context processor that would add the
> > > verified HTTP_HOST to template context? Then you could do just
>
> > > {% extend MY_VERIFIED_HTTP_HOST %}
>
> > > See:
>
> >http://docs.djangoproject.com/en/dev/ref/request-response/#django.htt...
>
> >http://docs.djangoproject.com/en/dev/ref/templates/api/#writing-your-...
>
> > request.META['HTTP_HOST'] is also the primary mechanism for
> > determining which website to serve when doing virtual hosting, IE if
> > you use apache and your site is hosted in a structure like:
>
> > NameVirtualHost *:80
> > <VirtualHost *:80>
> >   ServerNamewww.foo.com
> >   ServerAlias *.foo.com *.bar.com *.quuz.com
> >   ....
> > </VirtualHost>
>
> > Then that variable already is being verified.
>
> Yes and no.
>
> Apache uses it to resolve name based virtual hosts, but if it cant match it
> against a specific virtual host from memory it routes the request to the
> first VirtualHost which was found in the Apache configuration for that port.
>
> Have many times seen broken VirtualHost configurations which shouldn't work,
> but seem to, because the user only had one VirtualHost definition and so
> Apache was routing the request to it anyway.
>
> If you were going to be rigorous you would add a dummy VirtualHost as first
> in Apache configuration and have 'Deny from all' in it so that any attempts
> to access unknown host would fallback to this and get forbidden.
>
> Graham

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to [email protected].
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.

Reply via email to