Most web developers know it’s possible to serve one site on several domains or subdomains, using eg. the ServerAlias Apache directive. Sometimes this behaviour is not wanted: you want your main domain to be “foo.tld”, although “www.foo.tld” should work too, and maybe even some completely different domains.
This way it’s possible to have permalinks, and you won’t get bad points from search engine spiders who don’t like the same content to be available on several URIs.
In Django there’s the PREPEND_WWW setting, which will force all requests to be redirected to www.foo.bar when coming in on foo.bar, etc. This functionality is rather limited though. As I wanted to be able to have one unique main domain in my new application, I wrote a middleware which accomplishes this in a very generic way, using the django.contrib.sites framework. You need to add this middleware before all others in your settings file, even before the CommonMiddleware.
Here’s the code:
from django.contrib.sites.models import Site from django.http import HttpResponsePermanentRedirect from django.core.urlresolvers import resolve from django.core import urlresolvers from django.utils.http import urlquote class DomainRedirectMiddleware(object): def process_request(self, request): host = request.get_host() site = Site.objects.get_current() if host == site.domain: return None # Only redirect if the request is a valid path try: # One issue here: won't work when using django.contrib.flatpages # TODO: Make this work with flatpages resolve(request.path) except urlresolvers.Resolver404: return None new_uri = '%s://%s%s%s' % ( request.is_secure() and 'https' or 'http', site.domain, urlquote(request.path), (request.method == 'GET' and len(request.GET) > 0) and '?%s' % request.GET.urlencode() or '' ) return HttpResponsePermanentRedirect(new_uri)
Make sure you got the sites framework set up correctly when using this! As noted in the code, this doesn’t work with the Flatpages framework yet, this is TODO.