- Setup the project using the instructions from https://django-superapp.bringes.io/
- Setup
multi_tenant
app using the below instructions:
cd my_superapp;
cd superapp/apps;
django_superapp bootstrap-app \
--template-repo https://github.com/django-superapp/django-superapp-multi-tenant ./multi_tenant;
cd ../../;
- Make sure to define
main_settings['TENANT_MODEL'] = 'my_org_app.Organization'
in your settings.py file. - Update your
models.py
as follow
# my_org_app/models/organization.py
from django.db import models
from superapp.apps.multi_tenant.models import AppTenantModel
from django.utils.translation import gettext_lazy as _
class Organization(AppTenantModel):
name = models.CharField(_("Name"), max_length=255)
class TenantMeta:
tenant_field_name = "id"
@classmethod
def get_tenants_for_user(cls, user):
"""
Check if the user can access this tenant model instance.
This method should be overridden in subclasses to implement
specific access control logic.
"""
if user.is_superuser:
# If the user is a superuser, they can access all tenants
return cls.all_objects.all()
return cls.all_objects.filter(users__user=user, users__role="admin", users__is_active=True)
def __str__(self):
return self.name
# my_org_app/models/organization_user.py
from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _
from django_multitenant.fields import TenantForeignKey
from superapp.apps.easywindow.models.organization import Organization
from superapp.apps.multi_tenant.models import AppAwareTenantModel
class OrganizationUser(AppAwareTenantModel):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='organization_users',
null=True,
blank=True,
)
organization = TenantForeignKey(Organization, on_delete=models.CASCADE, related_name='users')
role = models.CharField(_("Role"), choices=[], max_length=100)
is_active = models.BooleanField(_("Is active"), default=True)
class TenantMeta:
tenant_field_name = "organization_id"
class Meta:
verbose_name = _("Organization User")
verbose_name_plural = _("Organization Users")
unique_together = ["organization", "user"]
def __str__(self):
return f"{self.user} - {self.organization}"
# my_org_app/models/organization_products.py
from django.db import models
from django.utils.translation import gettext_lazy as _
from django_multitenant.fields import TenantForeignKey
from superapp.apps.easywindow.models.organization import Organization
from superapp.apps.multi_tenant.models import AppAwareTenantModel
class OrganizationProduct(AppAwareTenantModel):
organization = TenantForeignKey(Organization, on_delete=models.CASCADE, related_name='profiles')
name = models.CharField(_("Name"), max_length=255)
class TenantMeta:
tenant_field_name = "organization_id"
class Meta:
unique_together = ['id','organization',]
ordering = ['organization', 'order', 'profile__name']
verbose_name = _("Organization Product")
verbose_name_plural = _("Organization Products")
def __str__(self):
return self.name
python manage.py tenant_dumpdata --tenant <tenant_pk> --output <filename>.json app_name.model_name
python manage.py tenant_loaddata --tenant <tenant_pk> <filename>.json
(obs, if <tenant_pk> is different from the one in the json file, all the fixtures will be imported in the specified tenant)
For more information please check out the following documentation: