Реализована полноценная система мультитенантности на базе django-tenants. Каждый магазин получает изолированную схему БД и поддомен. Основные компоненты: Django-tenants интеграция: - Модели Client (тенант) и Domain в приложении tenants/ - Разделение на SHARED_APPS и TENANT_APPS - Public schema для общей админки - Tenant schemas для изолированных данных магазинов Система регистрации магазинов: - Публичная форма регистрации на /register/ - Модель TenantRegistration для заявок со статусами (pending/approved/rejected) - Валидация schema_name (латиница, 3-63 символа, уникальность) - Проверка на зарезервированные имена (admin, api, www и т.д.) - Админ-панель для модерации заявок с кнопками активации/отклонения Система подписок: - Модель Subscription с планами (триал 90 дней, месяц, квартал, год) - Автоматическое создание триальной подписки при активации - Методы is_expired() и days_left() для проверки статуса - Цветовая индикация в админке (зеленый/оранжевый/красный) Приложения: - tenants/ - управление тенантами, регистрация, подписки - shops/ - точки магазинов/самовывоза (tenant app) - Обновлены миграции для всех приложений Утилиты: - switch_to_tenant.py - переключение между схемами тенантов - Обновлены image_processor и image_service Конфигурация: - urls_public.py - роуты для public schema (админка + регистрация) - urls.py - роуты для tenant schemas (магазины) - requirements.txt - добавлены django-tenants, django-environ, phonenumber-field Документация: - DJANGO_TENANTS_SETUP.md - настройка мультитенантности - TENANT_REGISTRATION_GUIDE.md - руководство по регистрации - QUICK_START.md - быстрый старт - START_HERE.md - общая документация Использование: 1. Пользователь: http://localhost:8000/register/ → заполняет форму 2. Админ: http://localhost:8000/admin/ → активирует заявку 3. Результат: http://{schema_name}.localhost:8000/ - готовый магазин 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
9.2 KiB
Настройка Django Tenants для multi-tenancy
Этот проект настроен как SaaS-платформа с поддержкой multi-tenancy через django-tenants. Каждый владелец магазина получает свой поддомен и изолированную схему БД в PostgreSQL.
Шаг 1: Установка PostgreSQL
Вариант A: Установка локально (Windows)
- Скачайте PostgreSQL с https://www.postgresql.org/download/windows/
- Установите PostgreSQL (запомните пароль для пользователя
postgres) - Откройте pgAdmin или psql и создайте базу данных:
CREATE DATABASE inventory_db;
Вариант B: Использование Docker (рекомендуется)
docker run --name inventory-postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=inventory_db \
-p 5432:5432 \
-d postgres:15
Шаг 2: Установка зависимостей
pip install -r requirements.txt
Это установит:
django-tenants==3.7.0psycopg2-binary==2.9.10- и другие зависимости
Шаг 3: Настройка подключения к БД
Откройте myproject/settings.py и при необходимости измените параметры подключения:
DATABASES = {
'default': {
'ENGINE': 'django_tenants.postgresql_backend',
'NAME': 'inventory_db',
'USER': 'postgres',
'PASSWORD': 'postgres', # ВАШ ПАРОЛЬ
'HOST': 'localhost',
'PORT': '5432',
}
}
Шаг 4: Создание миграций
# Создать миграции для всех приложений
python manage.py makemigrations
# Применить миграции для public схемы
python manage.py migrate_schemas --shared
Шаг 5: Создание публичного тенанта
Django-tenants требует создания public тенанта для работы главного домена (inventory.by):
python manage.py shell
from tenants.models import Client, Domain
# Создать public тенанта
public_tenant = Client.objects.create(
schema_name='public',
name='Главный домен',
owner_email='admin@inventory.by',
owner_name='Администратор'
)
# Создать домен для public
public_domain = Domain.objects.create(
domain='localhost', # Для локальной разработки
tenant=public_tenant,
is_primary=True
)
print(f'Public тенант создан: {public_tenant}')
print(f'Public домен создан: {public_domain}')
exit()
Шаг 6: Создание суперпользователя
# Создать суперпользователя в public схеме
python manage.py createsuperuser --schema=public
Введите:
- Email: ваш email
- Name: ваше имя
- Password: ваш пароль
Шаг 7: Создание тестового магазина (тенанта)
python manage.py create_tenant
Введите данные:
- Название магазина: Тестовый Магазин
- Схема БД: shop1
- Домен: shop1.localhost (или оставьте по умолчанию)
- Имя владельца: Иван Иванов
- Email: shop1@example.com
- Телефон: (опционально)
Команда автоматически:
- Создаст тенанта в таблице
Client - Создаст домен в таблице
Domain - Создаст схему БД
shop1в PostgreSQL - Применит все миграции к схеме
shop1
Шаг 8: Настройка hosts файла
Для локального тестирования добавьте в файл hosts:
Windows: C:\Windows\System32\drivers\etc\hosts
Linux/Mac: /etc/hosts
127.0.0.1 localhost
127.0.0.1 shop1.localhost
127.0.0.1 shop2.localhost
Шаг 9: Запуск сервера
python manage.py runserver 0.0.0.0:8000
Шаг 10: Тестирование
Доступ к админке супер-администратора (Public схема):
- URL: http://localhost:8000/admin/
- Логин: email и пароль суперпользователя
- Здесь вы можете управлять тенантами (магазинами)
Доступ к админке магазина (Tenant схема):
- URL: http://shop1.localhost:8000/admin/
- Создайте суперпользователя для магазина:
python manage.py tenant_command createsuperuser --schema=shop1 - Здесь владелец магазина управляет своими товарами, заказами, клиентами
Архитектура проекта
Public Schema (схема public):
Доступна по адресу: localhost или inventory.by
Модели:
Client- информация о тенантах (магазинах)Domain- домены тенантов
Кто имеет доступ:
- Супер-администратор (вы)
Для чего:
- Управление тенантами
- Просмотр статистики
- Биллинг (в будущем)
Tenant Schema (схемы shop1, shop2, и т.д.):
Доступна по поддоменам: shop1.localhost, shop2.localhost
Модели:
Customer- клиенты магазинаAddress- адреса клиентовShop- точки магазинаProduct,ProductKit,Category- товарыOrder,OrderItem- заказыInventory- складской учетCustomUser- сотрудники (для будущего)
Кто имеет доступ:
- Владелец магазина
- Сотрудники магазина (в будущем)
Для чего:
- Управление товарами
- Обработка заказов
- Работа с клиентами
- Складской учет
Полезные команды
Создать тенанта:
python manage.py create_tenant
Применить миграции ко всем тенантам:
python manage.py migrate_schemas
Применить миграции только к public:
python manage.py migrate_schemas --shared
Применить миграции к конкретному тенанту:
python manage.py migrate_schemas --schema=shop1
Выполнить команду для конкретного тенанта:
python manage.py tenant_command <command> --schema=shop1
Например:
python manage.py tenant_command createsuperuser --schema=shop1
python manage.py tenant_command loaddata data.json --schema=shop1
Список всех тенантов:
python manage.py shell
from tenants.models import Client
for tenant in Client.objects.all():
print(f'{tenant.name}: {tenant.schema_name}')
Устранение проблем
Ошибка: "No tenant found for hostname"
- Проверьте, что домен добавлен в hosts файл
- Проверьте, что домен существует в таблице
Domain - Проверьте, что вы обращаетесь к правильному поддомену
Ошибка: "relation does not exist"
- Запустите миграции:
python manage.py migrate_schemas - Проверьте, что схема создана в PostgreSQL
Ошибка подключения к PostgreSQL:
- Проверьте, что PostgreSQL запущен
- Проверьте параметры подключения в
settings.py - Проверьте, что база данных
inventory_dbсуществует
Продакшн
Для продакшна (на сервере):
-
Измените
settings.py:DEBUG = False ALLOWED_HOSTS = ['.inventory.by'] -
Настройте DNS для поддоменов (wildcard):
*.inventory.by → ваш сервер -
Используйте реальные домены вместо localhost
-
Настройте PostgreSQL с безопасным паролем
-
Используйте environment variables для секретов
Следующие шаги
После успешной настройки:
- ✅ Создайте несколько тестовых магазинов
- ✅ Добавьте товары в каждый магазин
- ✅ Создайте тестовые заказы
- ✅ Проверьте изоляцию данных между магазинами
- 🔜 Разработайте веб-интерфейс для владельцев магазинов
- 🔜 Добавьте регистрацию новых магазинов через веб-форму
- 🔜 Реализуйте биллинг и тарифные планы