Django becomes quite inconvenient when you want to setup a site at non-root path of the domain. Thing goes more complex when there are more than one site in the same level (and maybe we have to add those dynamically.)
There are some solutions working for the non-root issue:
- http://opensourcemissions.wordpress.com/2010/03/12/finally-a-working-django-non-root-url-with-mod_wsgi/
- Using mod_wsgi or mod_python with declaration of parent environment
- ...
Depending on the request, context and the personal habits, we could select or combine some solutions with the other. Below is what I've done to achieve it. Although I don't think it's optimized enough, it works.
1. Write an TemplateTag and some lines of Javascript for getting the current Django site ID/name and setting the appropriate cookie.
2. Put the combination of Javascript and TemplateTag above to the base.html of the site
3. Write the WSGI script
from os.path import dirname
os.environ['DJANGO_SETTINGS_MODULE'] = 'djsite.settings'
folders = []
folders.append(dirname(dirname(__file__)))
folders.append(dirname(folders[0]))
for folder in folders:
sys.path.append(folder)
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
4. Configure Apache to make it talk with users and the Django sites
# set the virtual host, mod_rewrite,..
ServerName django.vn
ErrorLog logs/subdjangos-error.log
CustomLog logs/subdjangos-access.log common
RewriteEngine On
RewriteOptions MaxRedirects=10
# declare the first site: Foo
<Directory /opt/subsites/foo/static>
Order allow,deny
Allow from all
</Directory>
Alias /foo/media/ /opt/subsites/foo/media/
<Directory /opt/subsites/foo/media>
Order allow,deny
Allow from all
</Directory>
RewriteCond %{REQUEST_URI} ^/((foo/.*$)|(foo$))
RewriteRule ^ - [L]
WSGIScriptAlias /foo /opt/subsites/foo/djsite.wsgi
# declare the second site: Bar
<Directory /opt/subsites/bar/static>
Order allow,deny
Allow from all
</Directory>
Alias /bar/media/ /opt/subsites/bar/media/
<Directory /opt/subsites/bar/media>
Order allow,deny
Allow from all
</Directory>
RewriteCond %{REQUEST_URI} ^/((bar/.*$)|(bar$))
RewriteRule ^ - [L]
WSGIScriptAlias /bar /opt/subsites/bar/djsite.wsgi
# check and deal with existing cookie
RewriteRule ^/(?!foo)(.*) /foo/$1 [R,L]
RewriteCond %{HTTP_COOKIE} dj_site_name=bar
RewriteRule ^/(?!bar)(.*) /bar/$1 [R,L]
</VirtualHost>
OK, here are some explanations:
RewriteRule ^ - [L]
The RewriteCond checks the request URI if bar/ is at the beginning or not. If True, Apache will cancel all other Rewrite lines and will pass the request to WSGIScriptAlias:
In case of not satisfied, the cookie (here is dj_site_name) will be checked for presence. That is the cookie which is set from the Javascript inside base.html
RewriteRule ^/(?!foo)(.*) /foo/$1 [R,L]
If the cookie value is "foo", all the requested URIs will be added with "/foo" as prefix. After redirection, WSGIScriptAlias will take the request and process it.
That is it.