Django|Using Subdomains with Django
rossp.org - Using Subdomains with Django
menu
find me
Archives
- Jun 2009
- Apr 2009
- Feb 2009
- Jan 2009
- Dec 2008
- Oct 2008
- Sep 2008
- Aug 2008
- Jul 2008
- Jun 2008
- May 2008
- Apr 2008
- Mar 2008
- Feb 2008
- Jan 2008
- Dec 2007
- Nov 2007
- Oct 2007
- Sep 2007
- Aug 2007
- Jul 2007
- Jun 2007
- May 2007
- Apr 2007
- Feb 2007
- Jan 2007
- Dec 2006
- Nov 2006
- Aug 2006
- Jul 2006
- Jun 2006
- May 2006
- Feb 2006
- Jan 2006
RSS Feeds
Links
Using Subdomains with Django
As a part of my previously mentioned upcoming bridal gift registry project (which, by the way, performed outstandingly in it's most important private beta ever - my own wedding) I'm giving each user (in this sense, a user is a couple close to getting married) their own subdomain off of the main website - instead of having a URL to their registry like http://yourdomain.com/registries/view/?id=1048 there are beautiful URL's like http://couplesnames.yourdomain.com.
Getting this working was really quite simple, and it's something that I can see being useful for SAAS projects - just take a look at the 37signals projects such as Basecamp and the way they handle per-company logins: each company has it's own subdomain.
The first thing that needs to be done is server configuration. Your domain name needs to have a wildcard entry setup (eg *.yourdomain.com), using Bind9 this is as easy as adding the following line to your domain name config. For other setups, speak to your web hosting provider.
* CNAME yourdomain.com.
Next, configure your web server software to answer requests for *.yourdomain.com the same way as www.yourdomain.com. I'm assuming that www.yourdomain.com already works, and that you're using Apache - again, YMMV so speak to your hosting provider. In Apache, just add the following line to your yourdomain.com virtual host configuration:
ServerAlias *.yourdomain.com
After restarting your DNS & web server software, you'll find that going to http://anything.yourdomain.com shows up the same result as http://www.yourdomain.com. Perfect.
Lastly you need to configure Django to treat subdomains differently. In this case I'm making another assumption, that Django is handling requests for yourdomain.com, and that there is a view already in place (eg via urls.py) for handling requests for the root of the domain. I'm also assuming content for your "main page" (eg, anything that's not a subdomain) is handled by other views, and that your main page is under /mypage/.
My 'index' view therefore looks like this:
def index(request): django_site = Site.objects.get_current() if request.META['HTTP_HOST'] == django_site.domain: # The visitor has hit the main webpage, so redirect to /mypage/ return HttpResponseRedirect('/mypage/') # Split the domain into it's parts, remove the main part of the domain # from the requested host, and we're left with one variable: 'subdomain'. # We also strip out the 'www.' non web-savvy users often type 'www' in # front of every website they visit, so let's not show them an error message! domain_parts = django_site.domain.split(".") domain = ".".join(domain_parts[1:]) subdomain = request.META['HTTP_HOST'].replace(domain, '').replace('.', '').replace('www', '') # You can now access your data models using 'subdomain', eg: couple = Couple.objects.get(subdomain=subdomain)
You can see I'm referring to a model called Couple, with a field named 'Subdomain'. All you need to do is refer to your own model with a 'subdomain' key and you're in business - just remember to enforce unique subdomains at signup time! Lastly, ensure your current Django 'Site' entry (django.contrib.sites) is up to date with the domain set to 'www.yourdomain.com'.
From here you can customise what's shown to the visitor based off of the subdomain they've hit. Very easy to setup, and potentially very powerful - especially in environments where people need something as easy as possible to remember or as unique as possible.
© Copyright 2008 Ross Poulton. All Rights Reserved. Opinions expressed here are my own, and nare not those of my employer or any other party. Powered by Django.
No comments:
Post a Comment