Running Mango alongside other Django apps on different subdomains
Over on MTG apps I'm using Dave Fowler's subdomains middleware to run a Mango blog and another Django app on different subdomains.
Getting this up and running locally was a piece of cake but mirroring the setup on my WebFaction slice proved to be more challenging. The quick fix would have been to create two separate Django projects; one for each app. This would have resulted in unnecessary duplication of shared settings, though, so I was thrilled to find a workable solution in the end.
Here's the project-level urls.py:
from django.conf.urls.defaults import * from django.core.urlresolvers import resolve import app1.urls import app2.urls def route_request(request): urlconf = app2.urls if request.subdomain == 'app2' else app1.urls view, args, kwargs = resolve(request.path, urlconf=urlconf) return view(request, *args, **kwargs) urlpatterns = patterns('', (r'', lambda request: route_request(request)), # associate urlconfs with their respective apps (r'', include(app1.urls, app_name='app1')), (r'', include(app2.urls, app_name='app2')), )
It's worth noting that I'm including the urlconfs explicitly even though
the requests are all handled by route_request. Django's URL resolver relies
on urlconfs and apps being associated in this way. Without this information
the url template tag throws horrible NoReverseMatch exceptions.
This setup — without violating DRY — appeared to be getting the job done, but today I noticed that it had broken Django's automatic slash appending. Thankfully, it's possible to add this functionality manually without messing with Mango's source, by taking advantage of the fact that Mango's default URL resolution can be overridden.
# mango/urls/custom.py from django.conf.urls.defaults import * from django.core.urlresolvers import reverse from django.http import HttpResponsePermanentRedirect from mango.handlers import moderate from mango.views import archives, search urlpatterns = patterns('', (r'^archive$', lambda request: HttpResponsePermanentRedirect(reverse(archives))), (r'^moderate/(approve|delete|spam|close)$', moderate), (r'^search$', search), (r'^.*[^/]$', lambda request: HttpResponsePermanentRedirect('%s/' % request.path)), )
The fourth tuple is responsible for appending slashes. The preceding patterns act as guards to ensure that slashes are not appended inappropriately. (Mango is extremely lenient as far as the archives page is concerned – "archive", "archive/", and "archives" will all take you to "archives/".)