Skip to content

DRF with Django Tenant Users #679

Description

@thubamamba

I have been trying to find an implementation on Django Rest Framework, to no avail. Reading the docs, I don't see anything that I have missed, I am able to create public and additional tenants, however, when testing, users who don't even belong to a tenant are able to create resources for those respective tenants. I really would appreciate the guidance here. :

from django.db import models
from django.utils import timezone
from django_tenants.models import DomainMixin, TenantMixin
from tenant_users.tenants.models import TenantBase


class Company(TenantBase):
    name = models.CharField(max_length=100, unique=True)
    paid_until = models.DateField(null=True, blank=True)
    is_active = models.BooleanField(default=False, blank=True)
    created = models.DateTimeField(default=timezone.now)
    auto_create_schema = True

    class Meta:
        ordering = ('-created',)

    def __str__(self):
        return f"{self.name}"


class Domain(DomainMixin):
    pass

In the custom user, I have:

from django.db import models
from django.core.validators import RegexValidator
from django.utils import timezone
from tenant_users.tenants.models import UserProfile
# Create your models here.
USERNAME_PATTERN = '^[a-z0-9+]{2,25}$'
USERNAME_ERROR_MESSAGE = 'invalid username formate'


class User(UserProfile):
    name = models.CharField(max_length=50)
    email = models.EmailField(max_length=255, unique=True)
    username = models.CharField(max_length=25, unique=True, validators=[
        RegexValidator(regex=USERNAME_PATTERN, message=USERNAME_ERROR_MESSAGE)])
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    created_date = models.DateTimeField(default=timezone.now)

    REQUIRED_FIELDS = ['name', 'password', 'email']
    USERNAME_FIELD = 'username'

Worth noting is that I am using SimpleJWT, with Djoser and the following is my config:

SHARED_APPS = [
    "django_tenants",   # Mandatory
    "jazzmin",
    # Everything below here is optional
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'tenant_users.permissions',
    'tenant_users.tenants',
    # Mandatory
    "companies",
    "accounts",
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Others apps
    'django_extensions',
    'corsheaders',
    'djoser',
    'drf_yasg',
    'rest_framework',
    'rest_framework.authtoken',
    "rest_framework_simplejwt",
    "storages",
]

TENANT_APPS = [
    "django_tenants",
    # Tenant-specific apps
    'guests',

    # Other apps
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'tenant_users.permissions',

    'rest_framework',
    'rest_framework.authtoken',
    'rest_framework_simplejwt',

    # Installed apps
    "drf_yasg",
    # 'jazzmin',
    'corsheaders',
    # "storages",
]

INSTALLED_APPS = list(SHARED_APPS) + [app for app in TENANT_APPS if app not in SHARED_APPS]

MIDDLEWARE = [
    "django_tenants.middleware.main.TenantMainMiddleware",  # Mandatory, must be 1st
    "corsheaders.middleware.CorsMiddleware",
   .....
]

ROOT_URLCONF = "drf_api.urls"
PUBLIC_SCHEMA_URLCONF = "drf_api.urls_public"

# Multitenancy
TENANT_MODEL = "companies.Company"
TENANT_DOMAIN_MODEL = "companies.Domain"
DEFAULT_FILE_STORAGE = "django_tenants.files.storage.TenantFileSystemStorage"   # each tenant will have a dedicated subdirectory for storing user-uploaded files
MULTITENANT_RELATIVE_MEDIA_ROOT = ""  # (default: create sub-directory for each tenant)
SHOW_PUBLIC_IF_NO_TENANT_FOUND = True  # (default: False) - If True, the public schema will be used if no tenant is found
AUTHENTICATION_BACKENDS = ("tenant_users.permissions.backend.UserBackend",)
TENANT_USERS_ACCESS_ERROR_MESSAGE = "Custom access denied message."
TENANT_USERS_DOMAIN = "localhost:8000"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions