Third party apps

Open source Django multi tenancy apps

There are number of third party Django apps which add multi tenancy to Django.

Some of them are

We will look in detail at Django tenant schemas, which is our opinion is the most mature of the Django multi tenancy solutions.

A tour of django-tenant-schemas

Install django-tenant-schemas using pip. pip install django-tenant-schemas. Verify the version of django-tenant-schemas that got installed.

$ pip freeze | grep django-tenant-schemas
django-tenant-schemas==1.9.0

We will start from our non tenant aware Polls app and add multi tenancy using django-tenant-schemas.

Create a new database, and make sure your Django app picks up the new DB by updating the DATABASE_URL environment var.

Update your settings to use the tenant-schemas DATABASE_BACKEND and tenant-schemas DATABASE_ROUTERS

DATABASES["default"]["ENGINE"] = "tenant_schemas.postgresql_backend"
# ...
DATABASE_ROUTERS = ("tenant_schemas.routers.TenantSyncRouter",)

The postgresql_backend will ensure that the connection has the correct tenant set, and the TenantSyncRouter will ensure that the migrations run correctly.

Then create a new app called tenants with manage.py startapp, and create a new Client model

from tenant_schemas.models import TenantMixin


class Client(TenantMixin):
    name = models.CharField(max_length=100)

In your settings, change the middleware and set the TENANT_MODEL.

TENANT_MODEL = "tenants.Client"
# ...

MIDDLEWARE = [
    "tenant_schemas.middleware.TenantMiddleware",
    # ...
    ]

tenant-schemas comes with the concept of SHARED_APPS and TENANT_APPS. The apps in SHARED_APPS have their tables in public schema, while the apps in TENANT_APPS have their tables in tenant specific schemas.

SHARED_APPS = ["tenant_schemas", "tenants"]

TENANT_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "rest_framework",
    "rest_framework.authtoken",
    "polls",
]

INSTALLED_APPS = SHARED_APPS + TENANT_APPS

We are almost done. We need to

  • Run the migrations in the public schema
  • Create the tenants and run migrations in all the tenant schemas
  • Create a superuser in tenant schemas

tenant-schemas has the migrate_schemas which replaces the migrate command. It is tenant aware and will sync SHARED_APPS to public schema, and TENANT_APPS to tenant specific schemas.

Run python manage.py migrate_schemas --shared to sync the public tables.

The run a python shell using python manage.py shell, and create the two tenants, using

Client.objects.create(name="thor",
    schema_name="thor", domain_url="thor.polls.local")
Client.objects.create(name="potter",
    schema_name="potter", domain_url="potter.polls.local")

This will create the schemas in the table and run the migrations. You now need to create the superuser in the tenant schema so that you can access the admin. The tenant_command command allow running any Django command in the context of any tenant.

   python manage.py tenant_command createsuperuser

And we are done. We can now access the tenant admins, create polls and view the tenant specific API endpoints.

The code for this chapter is available at https://github.com/agiliq/building-multi-tenant-applications-with-django/tree/master/tenant-schemas-demo .