Django makes it really easy to add additional data onto requests for use within the view. For example, we can parse out the subdomain on the request's META and attach it as a separate property on the request by using middleware.
class SubdomainMiddleware:
def process_request(self, request):
"""
Parse out the subdomain from the request
"""
host = request.META.get('HTTP_HOST', '')
host_s = host.replace('www.', '').split('.')
request.subdomain = None
if len(host_s) > 2:
request.subdomain = host_s[0]
If you add data with middleware to your request, you can access that newly added data further down the line. Here we'll use the parsed subdomain to determine something like what organization is accessing your application. This approach is useful for apps that are deployed with a DNS setup with wildcard subdomains that all point to a single instance and the person accessing the app wants a skinned version dependent on the access point.
class OrganizationMiddleware:
def process_request(self, request):
"""
Determine the organization based on the subdomain
"""
try:
request.org = Organization.objects.get(domain=request.subdomain)
except Organization.DoesNotExist:
request.org = None
Remember that order matters when having middleware depend on one another. For requests, you'll want the dependent middleware to be placed after the dependency.
MIDDLEWARE_CLASSES = [
...
'myapp.middleware.SubdomainMiddleware',
'myapp.middleware.OrganizationMiddleware',
...
]