{% extends 'base.html' %} {% block title %}Tenant Tutorial{% endblock %} {% block summary %}

Welcome to the Tenant Tutorial!

This interactive tutorial will teach you how to use django-tenant-schemas.

{% endblock %} {% block instructions %} {% if need_sync %}

First Step: Sync your database

Your database is empty, so the first step is to sync it. We only want to sync the SHARED_APPS. For your convenience, here's the contents of SHARED_APPS:


Just run the command below on your shell to sync SHARED_APPS. Make sure your environment has Django and django-tenant-schemas available.

$ python manage.py migrate_schemas --shared

When you're done refresh this page.

{% elif no_public_tenant %}

Second Step: Create a public tenant

So how does django-tenant-schemas work?

django-tenant-schemas uses the request's hostname to try to find a tenant. When a match is found, PostgreSQL's search path is automatically set to be this tenant.


For this request, django-tenant-schemas couldn't find any tenant for the current address ({{ hostname }}). When no tenant is found, django-tenant-schemas normally returns a 404, but since this is a tutorial and no tenant exists yet, we let it proceed.

Recommended Tenant's URLs Structure

Let's assume you have your main website at trendy-sass.com. The recommended structure is to put your tenants at subdomains, like tenant1.trendy-sass.com, tenant2.trendy-sass.com and so forth.

Creating the public tenant

django-tenant-schemas requires a tenant for all addresses you use, including your main website, which we will from now on refer to as the public tenant.


Our model is called Customer and looks like this (taken from models.py):

class Client(TenantMixin):
    name = models.CharField(max_length=100)
    description = models.TextField(max_length=200)
    created_on = models.DateField(auto_now_add=True)

Let's create a tenant for our main website, located at {{ hostname }}. Open up a shell and enter the django shell:

$ ./manage.py shell

To create a tenant run the following commands:

from customers.models import Client
Client(domain_url='{{ hostname }}',
    schema_name='public',
    name='Trendy SaSS',
    description='Public Tenant').save()

Done! django-tenant-schemas will now be able to locate our public tenant and won't return 404. Refresh this page to see the next step.

{% elif only_public_tenant %}

Third Step: Create Tenants

We've already created the public tenant, now it's time to create some tenants for subdomains. I assume you're running this on your local machine, so the easiest way to simulate domains is to edit your hosts file. Here are instructions for all platforms. I'll assume you're on Linux.

$ sudo nano /etc/hosts 

Add the following lines:

127.0.0.1	tenant1.trendy-sass.com
127.0.0.1	tenant2.trendy-sass.com

We're basically tricking our computer to think both tenant1.trendy-sass.com and tenant2.trendy-sass.com point to 127.0.0.1. Once you're done, try visiting tenant1.trendy-sass.com, you should get a django 404. As we have previously mentioned, we don't have a tenant there yet, so a 404 will be thrown.


We can now add tenants using these URLs and our project will be able to find them and identify them as our tenants. Back to the django shell:

$ ./manage.py shell
from customers.models import Client
Client(domain_url='tenant1.trendy-sass.com',
    schema_name='tenant1',
    name='Tenant1 - Awesome',
    description='Our first real tenant, awesome!').save()

Saving a tenant that didn't exist before will create their schema and sync TENANT_APPS automatically. You should see the following lines as the result.

{% if DJANGO17 %}
Operations to perform:
  Synchronize unmigrated apps: customers, tenant_schemas
  Apply all migrations: contenttypes, auth, sessions
Synchronizing apps without migrations:
  Creating tables...
  Installing custom SQL...
  Installing indexes...
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying sessions.0001_initial... OK
{% else %}
=== Running syncdb for schema: tenant1
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_groups
Creating table auth_user_user_permissions
Creating table auth_user
Creating table django_content_type
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
{% endif %}

This means your tenant was installed successfully. Now create the second tenant.

Client(domain_url='tenant2.trendy-sass.com',
    schema_name='tenant2',
    name='Tenant2 - Even Awesome-r',
    description='A second tenant, even more awesome!').save()

Now try visiting tenant1.trendy-sass.com and tenant2.trendy-sass.com or refresh this page.

{% else %}

Tutorial Complete!

Well done, you have completed the tutorial! Use the bottom menu to see your tenants.

Where to go from here

There are some interesting features that we did not cover.

{% endif %} {% endblock %}