Django multi tenancy

For ease of use, Django packages as compiled a page full of every possible existing django package that can accomplish this. However below is my own simple implementation


I modified my nginx proxy config to use the following

server_name ~(?<short_url>\w+)\.domainurl\.com$;

... stuff related to static files here
location / {
        proxy_set_header X-CustomUrl $short_url;
        .... other proxy settings
}

What this does is create a variable inside a request header that can then be used within Django. This variable I then used within a custom middleware to extend a request with a reference to the model which allows its use anywhere.

class CompanyMiddleware(object):    
    def process_request(self, request):
        if settings.DEBUG:
            request.company = CompanyClass.objects.get(id=1)
            return None

        short_url = request.META.get("HTTP_X_CUSTOMURL")

        try:
            company = CompanyClass.objects.get(short_url=short_url)
        except Model.DoesNotExist:
            return HttpResponseBadRequest('Company not found')

        request.company = company

        return None

Examples:

www.companya.domainurl.com   # short_url is companya
test.domainurl.com           # short_url is test

To use this within a template, context processors must be added to the settings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    "django.contrib.auth.context_processors.auth",
    "django.core.context_processors.debug",
    "django.core.context_processors.i18n",
    "django.core.context_processors.media",
    'django.core.context_processors.request'  # This one in particular
)

Leave a Comment