This application enables django powered websites to have multiple tenants via PostgreSQL schemas. A vital feature for every Software-as-a-Service website.
Django provides currently no simple way to support multiple tenants using the same project instance, even when only the data is different. Because we don't want you running many copies of your project, you'll be able to have:
A schema can be seen as a directory in an operating system, each directory (schema) with it's own set of files (tables and objects). This allows the same table name and objects to be used in different schemas without conflict. For an accurate description on schemas, see PostgreSQL's official documentation on schemas.
There are typically three solutions for solving the multitenancy problem.
This application implements the second approach, which in our opinion, represents the ideal compromise between simplicity and performance.
Each solution has it's up and down sides, for a more in-depth discussion, see Microsoft's excellent article on Multi-Tenant Data Architecture.
Tenants are identified via their host name (i.e tenant.domain.com). This information is stored on a table on the public
schema. Whenever a request is made, the host name is used to match a tenant in the database. If there's a match, the search path is updated to use this tenant's schema. So from now on all queries will take place at the tenant's schema. For example, suppose you have a tenant customer
at http://customer.example.com. Any request incoming at customer.example.com
will automatically use customer
's schema and make the tenant available at the request. If no tenant is found, a 404 error is raised. This also means you should have a tenant for your main domain, typically using the public
schema. For more information please read the setup section.
Each tenant has its data on a specific schema. Use a single project instance to serve as many as you want.
Tenant-specific and shared appsTenant-specific apps do not share their data between tenants, but you can also have shared apps where the information is always available and shared between all.
You can have different views for http://customer.example.com/
and http://example.com/
, even though Django only uses the string after the host name to identify which view to serve.
Everyone loves magic! You'll be able to have all this barely having to change your code!
This is just a short setup guide, it is strongly recommended that you read the complete version at django-tenant-schemas.readthedocs.io.
Your DATABASE_ENGINE
setting needs to be changed to
DATABASES = { 'default': { 'ENGINE': 'tenant_schemas.postgresql_backend', # .. } }
Add the middleware tenant_schemas.middleware.TenantMiddleware
to the top of MIDDLEWARE_CLASSES
, so that each request can be set to use the correct schema.
MIDDLEWARE_CLASSES = ( 'tenant_schemas.middleware.TenantMiddleware', #... )
Add tenant_schemas.routers.TenantSyncRouter
to your DATABASE_ROUTERS setting, so that the correct apps can be synced, depending on what's being synced (shared or tenant).
DATABASE_ROUTERS = ( 'tenant_schemas.routers.TenantSyncRouter', )
Add tenant_schemas
to your INSTALLED_APPS
.
from django.db import models from tenant_schemas.models import TenantMixin class Client(TenantMixin): name = models.CharField(max_length=100) paid_until = models.DateField() on_trial = models.BooleanField() created_on = models.DateField(auto_now_add=True)
Define on settings.py
which model is your tenant model. Assuming you created Client
inside an app named customers
, your TENANT_MODEL
should look like this:
TENANT_MODEL = "customers.Client" # app.Model
Now run migrate_schemas
to sync your apps to the public
schema.
python manage.py migrate_schemas --shared
Create your tenants just like a normal django model. Calling save
will automatically create and sync/migrate the schema.
from customers.models import Client # create your public tenant tenant = Client(domain_url='tenant.my-domain.com', schema_name='tenant1', name='My First Tenant', paid_until='2014-12-05', on_trial=True) tenant.save()
Any request made to tenant.my-domain.com
will now automatically set your PostgreSQL's search_path
to tenant1
and public
, making shared apps available too. This means that any call to the methods filter
, get
, save
, delete
or any other function involving a database connection will now be done at the tenant's schema, so you shouldn't need to change anything at your views.
You're all set, but we have left key details outside of this short tutorial, such as creating the public tenant and configuring shared and tenant specific apps. Complete instructions can be found at django-tenant-schemas.readthedocs.io.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4