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.














2 Responses to “Django domain redirect middleware”
Leave a comment