Put subdomains to work and build dynamic multi-tennant applications.
Single domain web sites are so boring. Custom subdomains are a great way to provide customization for customers of SaaS products and to differentiate content without resorting to long URL paths. Implementing subdomain support in a web application isn’t
The most efficient way to redirect requests based on subdomains is to use your front-end webserver, e.g. Nginx. This works well when you have only a few domains to redirect or when you know up front what all of those subdomains are. If you don’t know what this list includes, there’s a multitude, or you want someone else like a site manager to be able to update these, then it’s time to take a look at what the application layer can do.
In this example, we have a simple model which includes a subdomain and a URL to which that subdomain request should redirect. The subdomain entries have a unique subdomain name but the URL need not be, as we may want multiple entires redirecting to the same place.
The redirection itself is handled by a small piece of middleware, a simplified version of which is shared below.
The full domain is broken into its component parts and the primary
domain is ignored. Notice that this does assume your top-level domain
has one component plus the top-level domain. The typical redirect
response, e.g. return redirect('/myurl/')
includes only the absolute
URL, and since the goal here is to redirect to an entirely new domain
it’s important to include the full path of the redirect. The middleware
uses the get_full_path
method to ensure that the path plus any query
paramters are included in the redirect.
A note: if you’re using a deeper domain(s) like mydomain.co.uk then you’d need to adjust how you slice the domain.
The real benefit of using subdomains in a web application comes from providing unique content based on the subdomain, like a customized microsite or customer store. There are literally tens (well, tens of thousands) of examples of this on the web, and the redirection middleware above gets us almost all the way there.
What we want to do is not redirect but provide different responses, so
let’s look at an example. This code has some assumptions. It assumes
that you have a set of URL patterns for a primary domain, perhaps the
main application signup site, and then unique customer-based subdomains.
It assumes that the URL configuration in myapp
will provide the entire
root URL configuration for the subdomain responses, and that the
Account
model in the myapp
application is an identifier with a
unique subdomain. The models have been left out in this example.
Presuming you have added a new setting called DEFAULT_SITE_DOMAIN
such
as www.myapp.com, then the middleware will ignore all requests to that
domain. For all other requests it checks to see if the URL pattern
matches a pattern in the URL configuration for the subdomains
(frontend_urls
). If not, then it’s probably a bad link, and we
redirect back to the primary domain.
If there’s a match, all the middleware does is add the right account to
the request so that the views accessible via frontend_urls
can use
request.account
to filter objects and content for each request,
showing the right account name, users, page styles, etc.
Now go forth and leverage the synergistic powers of holistic subdomains.