Dynamic multi-site - running many sites from one Django instance

983 views
Skip to first unread message

berryp

unread,
Mar 20, 2010, 9:55:00 AM3/20/10
to Django users
Hi,

I am working on a project which needs to run any number of sites in
the same Django instance. Each site can be in many languages and must
have it's own set of templates and media. I have prototyped this using
the sites framework by setting the SITE_ID, MEDIA_ROOT and
TEMPLATE_DIRS at runtime in middleware in the process_request event
(see below). This is currently working perfectly for my requirements
but several sources suggest against altering the settings variables at
runtime. Can anyone suggest a more "best practice" approach or is this
really my only option? Having individual site settings files would not
work here as this needs to operate on a per-request basis. Also, it
wouldn't really be feasible for each site to have it's own Django
instance as this will be running in a load balanced environment and
would quickly become a real pain to manage and maintain.

Thanks in advance

Berry

My middleware (I've made minor alterations to the code for this
message so ignore any syntax errors):

class MultiSiteMiddleware:
def process_request(self, request):
settings.MEDIA_ROOT = settings.DEFAULT_MEDIA_ROOT

if request.path.startswith('/admin/'):
return

try:
host = request.get_host().rsplit(':', 1)[0] # strip port
from hostname
site = Site.objects.get(domain=host)
site_profile = SiteProfile.objects.get(site_id=site.id)
language_code = site_profile.default_language.code

prefix = '%s/%s' % (site_profile.path_name, language_code)

settings.SITE_ID = site.id
settings.LANGUAGES = site_profile.language_list
settings.MEDIA_ROOT = os.path.join(settings.PROJECT_PATH,
'media', 'sites', prefix)
settings.TEMPLATE_DIRS =
(os.path.join(settings.PROJECT_PATH, 'templates', 'sites', prefix),)

return

except Site.DoesNotExist:
return
HttpResponsePermanentRedirect(settings.NO_SITE_REDIRECT)

Tim Shaffer

unread,
Mar 22, 2010, 1:03:29 PM3/22/10
to Django users
How are you serving the Django project? Are you using Apache?
mod_python? mod_wsgi?

If you are using mod_python or mod_wsgi, you should be able to change
the DJANGO_SETTINGS_MODULE for each site. So basically for each site,
you would have a separate settings file in your project.

So for the first site, set your settings module. This is if using
mod_python, but it's similar for mod_wsgi.

SetEnv DJANGO_SETTINGS_MODULE project.settings_site1

Then for your second site, you can use a different settings module in
the same project.

SetEnv DJANGO_SETTINGS_MODULE project.settings_site2

An example of settings_site1.py would look like this. Just import all
the default settings, then overwrite what you need to.

from settings import *
SITE_ID = 1

I didn't test any of this. But it should work. In theory.

Tom Evans

unread,
Mar 22, 2010, 1:16:29 PM3/22/10
to django...@googlegroups.com

That would give you multiple sites from mutiple instances of one
codebase, where as I think the OP is looking for multiple sites from
one instance of one codebase.

Cheers

Tom

Tim Shaffer

unread,
Mar 22, 2010, 1:53:23 PM3/22/10
to Django users
It gives you multiple sites from one codebase with multiple settings
files. They are using the same project module. So your project would
look like this:

project
- app1
- app2
- settings.py
- settings_site1.py
- settings_site2.py
- urls.py

settings.py would contain all the settings like a normal django
project, then settings_site1 and settings_site2 could import all those
default settings and overwrite just the settings they need to (like
SITE_ID and MEDIA_ROOT).

Tom Evans

unread,
Mar 23, 2010, 5:29:30 AM3/23/10
to django...@googlegroups.com

That is fascinating, but if you had 20 sites, you would need to run 20
instances of the project.

Bjunix

unread,
Mar 23, 2010, 6:02:44 AM3/23/10
to Django users
You could also build your own "Sites framework" relying on other
things than settings files. Django's sites framework is not too
complex and if does not fit your need, I would just rebuild it
tailored to your needs.

On Mar 23, 10:29 am, Tom Evans <tevans...@googlemail.com> wrote:

berryp

unread,
Mar 23, 2010, 6:11:25 AM3/23/10
to Django users
Yes, this is exactly the problem. My code above takes care of
everything in one instance. It's starting to sound like this will be
the best solution. Building a custom sites framework may be overkill
for the sake of altering a few settings variables at run time. Hard to
know if my solution will run into any problems without testing in a
high load environment.

On Mar 23, 9:29 am, Tom Evans <tevans...@googlemail.com> wrote:

berryp

unread,
Mar 23, 2010, 6:13:38 AM3/23/10
to Django users
I will certainly look into this as it may give me a lot more control
but I don't want to end up with lots of added complexity for the sake
of conformity.

Nuno Maltez

unread,
Mar 23, 2010, 1:56:40 PM3/23/10
to django...@googlegroups.com


This is the method we use in production.

Nuno

Rolando Espinoza La Fuente

unread,
Mar 23, 2010, 4:57:10 PM3/23/10
to django...@googlegroups.com
On Tue, Mar 23, 2010 at 5:41 AM, berryp <berryp...@gmail.com> wrote:
> Yes, this is exactly the problem. My code above takes care of
> everything in one instance. It's starting to sound like this will be
> the best solution. Building a custom sites framework may be overkill
> for the sake of altering a few settings variables at run time. Hard to
> know if my solution will run into any problems without testing in a
> high load environment.
>

Few days ago I want the same: run multiple sites with one instance.

But in my case is for handling multiple subdomains. After looking at SITE_ID
implementation, I think changing it at runtime will break the CurrentSiteManager
with relies on SITE_ID. Also the issue of having multiple threads modifying
the settings.SITE_ID per request.

I didn't go further. Regards,

Rolando

Tim Shaffer

unread,
Mar 23, 2010, 9:53:42 PM3/23/10
to Django users
No, it would just be one instance of the project with 20 different
configuration files.

On Mar 23, 5:29 am, Tom Evans <tevans...@googlemail.com> wrote:

Graham Dumpleton

unread,
Mar 24, 2010, 12:52:53 AM3/24/10
to Django users

On Mar 24, 12:53 pm, Tim Shaffer <timster...@gmail.com> wrote:
> No, it would just be one instance of the project with 20 different
> configuration files.

There is the single instance of the code files on disk, but there
would be multiple instances of the loaded application in memory where
each instance in memory is configured differently based on which
settings file was used for that Python interpreter occurence.

You are using 'instance' to mean different things and why the likely
confusion.

Graham

Tim Shaffer

unread,
Mar 24, 2010, 8:12:39 AM3/24/10
to Django users
You are right. I understand now. I must have misread the original
request, because I now see that describes multiple instances in memory
wouldn't work properly.

On Mar 24, 12:52 am, Graham Dumpleton <graham.dumple...@gmail.com>
wrote:

Reply all
Reply to author
Forward
0 new messages