You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多租户架构新手:基于django-tenant-schema的动态API路由开发咨询

Hey there! I’ve built a couple of SaaS products using django-tenant-schema, so I totally get those early-stage head-scratchers you’re dealing with. Let’s break down your core requirements and answer the most common questions you’re probably asking right now.

Core Setup & Key Questions Answered

1. How to Auto-Create a Unique Schema for New Registered Clients?

This is the first critical step to get right. Here’s a straightforward workflow to tie schema creation to your customer registration flow:

  • First, make sure you’ve set up your TenantModel and DomainModel (usually named Client and Domain) as per the django-tenant-schema docs.
  • In your registration view, after validating the user’s sign-up form:
    1. Create a Client instance (your tenant object) — use a unique schema_name (like the customer’s lowercase business alias or a UUID to avoid conflicts) and fill in other required fields.
    2. Call client.save() — this method automatically creates the corresponding database schema behind the scenes.
    3. Link a subdomain to the new tenant by creating a Domain instance, setting its domain to something like acme.your-saas.com, marking it as primary, and saving it.

Example code snippet:

from django.shortcuts import redirect, render
from .models import Client, Domain
from .forms import ClientRegistrationForm

def register_client(request):
    if request.method == 'POST':
        form = ClientRegistrationForm(request.POST)
        if form.is_valid():
            # Create tenant object
            client = Client(
                schema_name=form.cleaned_data['schema_name'].lower(),
                name=form.cleaned_data['company_name'],
                on_trial=True
            )
            client.save()  # Triggers schema creation in DB

            # Link subdomain to tenant
            domain = Domain(
                domain=f"{form.cleaned_data['subdomain']}.your-saas.com",
                tenant=client,
                is_primary=True
            )
            domain.save()

            return redirect('registration_success')
    else:
        form = ClientRegistrationForm()
    return render(request, 'register.html', {'form': form})

Pro tip: Add a clean method to your registration form to enforce valid schema_name characters (only lowercase letters, numbers, and underscores — databases are picky about this!).

2. How to Route Requests to the Correct Schema via Subdomain?

django-tenant-schema has a built-in middleware that handles this automatically — you just need to place it correctly in your settings.py:

MIDDLEWARE = [
    # Tenant middleware must come first to handle schema switching early
    'django_tenants.middleware.main.TenantMainMiddleware',
    # Follow with standard Django middleware
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    # ... rest of your middleware
]

This middleware parses the incoming request’s domain, matches it to a Domain record, and switches to the corresponding schema. If no matching subdomain is found, it defaults to the PUBLIC_SCHEMA_NAME (usually set to public in your settings — this is where global, non-tenant-specific data lives).

For local development: Edit your system’s hosts file to map subdomains to 127.0.0.1 (e.g., 127.0.0.1 acme.localhost) so you can test subdomain routing locally.

3. How to Keep Public vs. Tenant Data Isolated?

  • Public data (like global FAQs, admin-only settings): Store these in models that don’t use the TenantManager. They’ll live in the public schema and be accessible across all tenants (though you’ll want to restrict edits to admins only).
  • Tenant-specific data (like customer users, orders): Use the TenantManager for these models to ensure they’re only stored in the tenant’s schema. Example:
from django.db import models
from django_tenants.models import TenantManager

class TenantUser(models.Model):
    full_name = models.CharField(max_length=100)
    email = models.EmailField(unique=True)

    objects = TenantManager()

    class Meta:
        verbose_name = "Tenant User"

4. Database Migration Pitfalls to Avoid

This is a super common pain point for new users:

  • To migrate public schema models: Run python manage.py migrate_schemas --shared — this applies migrations only to the public schema.
  • To migrate tenant-specific models: Run python manage.py migrate_schemas — this pushes migrations to all existing tenant schemas (and automatically applies them to new schemas as you create them).
  • Never use the standard python manage.py migrate — this will dump all models into the public schema and break your data isolation.

5. Local Debugging Hack

If you need to manually switch schemas to test data, use the schema_context context manager:

from django_tenants.utils import schema_context
from .models import TenantUser

def debug_tenant_data():
    with schema_context('acme'):
        # All operations here use the 'acme' schema
        tenant_users = TenantUser.objects.all()
        print([user.email for user in tenant_users])

内容的提问来源于stack exchange,提问作者Ramsk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:24:30