Skip to main content
You can enable multi-tenancy in your Django application using the Django-Tenants library, which allows each tenant to have its own subdomain and database schema, keeping data fully isolated. The following instructions guide you through setting up a Django-Tenants-enabled application on Sevalla. This example assumes you already have a deployed Django app. It is recommended to start with an empty database, as Django-Tenants applies migrations in a tenant-specific manner. Additionally, a custom domain is required for this setup, since each tenant will use a separate subdomain to implement the multi-tenancy structure.

Installation and settings

  1. Install the django-tenants library and add it to your dependencies.
  2. Update the database engine to use the Django-Tenants Postgres backend.
  3. A custom database router can then be added to settings.py.
  4. Add the TenantMainMiddleware to the MIDDLEWARE list. It should be added after CommonMiddleware to avoid any errors.

App and model

In this example, you’ll create two Django apps. The first, app, will contain the models used to manage tenants and domains, along with any views that are publicly accessible. The second app, dashboard, will be tenant-specific and will contain functionality and views intended only for individual tenants.
The Client and Domain models must be created in app/models.py. The Client model is used to create all tenants. The Domain model is used to associate subdomains with the tenants you create.

Other settings

Because some apps should be available globally across the project, while others should be isolated per tenant, you’ll need to adjust how INSTALLED_APPS is defined. Start by defining a SHARED_APPS list, which replaces the traditional INSTALLED_APPS and includes apps that are shared across all tenants. Next, create a TENANT_APPS list containing only the apps that should be available to individual tenants. Finally, define INSTALLED_APPS as a combination of both lists. The SHARED_APPS list should also include the django_tenants app and the main app application that manages tenants and domains.
In settings.py, configure Django-Tenants, so that it knows where your core tenant and domain models are defined.
Finally, in settings.py, replace the original ROOT_URLCONF with a new configuration pointing to urls_tenants, which you’ll create shortly. Then, define PUBLIC_SCHEMA_URLCONF to point to your original urls.py file, which will continue to handle all public (non-tenant) views.

Views

Below are two simple example views that illustrate the difference between public views and tenant-specific views.

Public View

This view lives in the shared app application and is accessible across the entire project, regardless of tenant.

Tenant-Specific View

This view belongs to the dashboard application and is only available within a tenant context. It uses request.tenant to access tenant-specific data.

Tenant URL Configuration

Next, create a urls_tenants.py file to define routes that should only be accessible to tenants. This file references views from the tenant-only dashboard app.

Public URL Configuration

Finally, keep your public routes in the existing urls.py file. These URLs are served from the public schema and remain accessible without a tenant context.

Deploying to Sevalla

Before deploying your application, create migrations to create the new models in the database.
Add a custom start command to prevent the default migrations from running.
Create a job process that runs before deployment that uses the migrate_schemas command from Django-Tenants.
Add a custom domain to your project so the subdomains work with django-tenants. You can now deploy your app in Deployments > Deploy now.

Create a Tenant

Once your app is deployed and you can see the public view on your page, add a tenant to the system. The tenant can be added through the web terminal. Use the bash web terminal, turn on the virtual environment, and then start a Django shell session.
Finally, create tenant and domain objects. Ensure the domain you use here matches the domain associated with your app.
Now you should be able to visit both your base domain and the tenant subdomain and see the public and tenant pages. You can also check your database and see that multiple schemas exist.