The Power of Django: 9 websites, 1 database

Django Logo

# Shoutouts
Most of this information came from Franchising: Running Multiple Sites from one Django Codebase by Huy Nguyen.  Really great article.

# Problem Context
For this project, we had to build 9 splash pages for a QR Code campaign. Each website had to have its own branding, and we were afforded the luxury of having a separate domain name for each page. By leveraging Django, we were able to provide a single page CMS to manage all of the splash pages while each splash page exists on its own domain.

# Solution
At some point from the initial request to the served template we had to distinguish which domain the request was generated from. This was accomplished at the apache level, using the django.wsgi script to add an environment variable equal to the domain the request originated from. The different django.wsgi scripts (1 for each domain) were then called by each virtual host individually.

At this point you should have a django project already created. There will be a single project that all of the individual sites are served from. Create the main project as you would at the beginning of any normal project.

# Setup Apache to call individual wsgi files
In your virtual host configuration file, you want to declare an alias that points to a common directory that will be used to hold the media for all the different domains, then point each domain at its own django.wsgi script:

Alias /media/ /directory/to/
WSGIScriptAlias / /path/to/django_project/apache/IndividualSiteName/django.wsgi

Now in /path/to/django_project/apache/ create a directory for each domain that will call your project. We will put the django.wsgi file from above into this directory.

$ cd /path/to/django_project/
$ mkdir apache
$ cd apache
$ mkdir IndividualSiteName
$ cd IndividualSiteName
$ vim django.wsgi

Inside each django.wsgi file, set the OVERLOAD_SITE variable to a name that identifies each domain uniquely. We will use this variable to tell django which CSS file to load, which template to use, which domain to search for media files, etc.

import os
import os.path
import sys


os.environ['DJANGO_SETTINGS_MODULE'] = 'django_project.settings'
os.environ['OVERLOAD_SITE'] = 'IndividualSiteName'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

Back up in your main project directory, were going to modify the file to overload the MEDIA_ROOT and MEDIA_URL variables based on the request from each domain. At the bottom of, add the function that will overload the variables:

import os
        OVERLOAD_SITE_MODULE ="site_overloads" + "." + OVERLOAD_SITE
        exec "from %s.settings import *" % (OVERLOAD_SITE_MODULE)
        # Overload the MEDIA_ROOT with site specific path
        # Overload the MEDIA_URL with site specific URL

For the MEDIA_ROOT and MEDIA_URL configuration at the top of the file, set a directory that will be a common directory used to host the media for all domains. If you override the MEDIA_URL for every domain, these settings will be ignored, so their values arn’t that important.

To set the override values, create the site_overloads directory that is referenced in the function we just added to It should be in the project root.  Inside site_overloads, create a directory for each individual domain that has the same name as the OVERLOAD_SITE variable from the django.wsgi file. Inside of site overloads, you must add a blank file, or django will not be able to pull files from the directory:

$ cd /path/to/django_project/
$ mkdir site_overloads
$ cd site_overloads
$ touch
$ mkdir IndividualSiteName
$ cd IndividualSiteName
$ touch

Now we will add a and file to each folder that will provide the overloads for each specific domain:

# Overload Default MEDIA_ROOT
# Use this if you want to serve up separate media for each domain
#OVERLOAD_MEDIA_ROOT = '/c2g/sites/'

# Overload Default MEDIA_URL

In your Apache Virtualhost config, recall that we set an Alias to /media/.  This Alias will allow you to put any domain in OVERLOAD_MEDIA_URL and have the single media directory exist at

New lets look at the  For our project, each domain was hosting a single splash page, so we were able to serve all requests by providing the context straight from the url, letting us completely skip making any views.

from django.conf.urls.defaults import *
from django.views.generic.simple import direct_to_template
from pages.models import Page

urlpatterns = patterns('',
(r'^$', direct_to_template, {'template': 'SingleTemplate.html',
'extra_context': {'page': Page.objects.get(name__exact='IndividualSiteName'),
'sliderImages': Page.objects.get(name__exact='IndividualSiteName')}}),

The above assumes  you have a Page class in your with a name field and a slider field.  You can modify the code to request anything you want from your models, or call a view for more indepth interaction.

Well, that should get you separate domains all hooked up to a single django app, capable of having a shared or individual media directories as well as individual domain names, all with a single page CMS for managing all your sites.


This entry was posted in Django. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *