Реализована полноценная система мультитенантности на базе 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>
12 KiB
Руководство по системе регистрации тенантов
Что реализовано
Создана полноценная система регистрации новых магазинов (тенантов) с ручной модерацией администратором.
1. Модели данных (tenants/models.py)
Client (обновлена)
- Добавлен
db_indexдля поляname(ускорение поиска) - Изменено поле
phoneнаPhoneNumberField(поддержка РБ/РФ форматов) - Обновлен
help_textдляowner_email(один email может быть у нескольких магазинов для супер-админа)
TenantRegistration (новая)
Модель заявки на регистрацию:
shop_name- название магазинаschema_name- желаемый поддомен (с валидацией regex)owner_email,owner_name,phone- контактные данныеstatus- статус заявки: pending/approved/rejectedprocessed_at,processed_by- данные обработкиtenant- ссылка на созданный тенант после активации
Subscription (новая)
Модель подписки:
plan- тип плана (триал 90 дней, месяц, квартал, год)started_at,expires_at- период действияis_active,auto_renew- статус и автопродление- Методы:
is_expired(),days_left(),create_trial(client)
RESERVED_SCHEMA_NAMES
Список зарезервированных поддоменов (admin, api, www, и т.д.)
2. Админ-панель (tenants/admin.py)
ClientAdmin (обновлена)
- Добавлена колонка
subscription_statusс цветовой индикацией - Разрешено редактирование
schema_nameпри создании нового тенанта - Запрещено удаление тенантов через админку (для безопасности)
TenantRegistrationAdmin (новая)
Функции:
- Список заявок с фильтрами по статусу и дате
- Кнопки "Активировать" / "Отклонить" для каждой заявки
- Массовые действия для обработки нескольких заявок
- При активации:
- Создается тенант (Client)
- Создается домен (например: myshop.localhost)
- Создается триальная подписка на 90 дней
- Заявка помечается как "Одобрено"
SubscriptionAdmin (новая)
- Просмотр и управление подписками
- Цветовая индикация истекающих подписок (красный < 0 дней, оранжевый < 7 дней)
3. Публичная форма регистрации
tenants/forms.py - TenantRegistrationForm
Валидация:
schema_name: приведение к lowercase, проверка длины (3-63 символа), проверка на зарезервированные имена, проверка уникальностиowner_email: проверка на дубликаты pending заявок
tenants/views.py
TenantRegistrationView- форма регистрацииRegistrationSuccessView- страница благодарности
HTML шаблоны
- base.html - базовый шаблон с Bootstrap 5
- registration_form.html - красивая форма с валидацией
- registration_success.html - страница с инструкциями
Как использовать
Для пользователей (владельцев будущих магазинов)
-
Откройте публичную форму регистрации:
http://localhost:8000/register/ -
Заполните форму:
- Название магазина
- Желаемый поддомен (только латиница, цифры, дефис)
- Ваше имя
- Телефон
-
После отправки увидите страницу благодарности
-
Ожидайте активации администратором (в течение 24 часов)
Для администратора
-
Войдите в админ-панель:
http://localhost:8000/admin/ -
Перейдите в раздел "Заявки на регистрацию"
-
Увидите список заявок со статусом "Ожидает проверки"
-
Для активации заявки:
- Кликните на кнопку "Активировать" справа от заявки
- ИЛИ выберите несколько заявок и используйте массовое действие
-
Что происходит при активации:
- Создается новый тенант (Client) с указанным schema_name
- Создается домен
{schema_name}.localhost - Создается триальная подписка на 90 дней
- Заявка помечается как "Одобрено"
- В поле "Созданный тенант" появляется ссылка на тенант
-
Для отклонения:
- Кликните "Отклонить"
- Заявка помечается как "Отклонено"
Доступ к магазинам
После активации магазин доступен по адресу:
http://{schema_name}.localhost:8000/
Например, для магазина с schema_name=myshop:
http://myshop.localhost:8000/
Управление подписками
Просмотр подписок
- Админ-панель → "Подписки"
- Видны все подписки с информацией:
- Тип плана
- Дата начала/окончания
- Осталось дней
- Истекла или нет
Продление подписки
- Откройте подписку тенанта
- Измените:
expires_at- новую дату окончанияplan- новый тип плана (если меняется)
- Сохраните
Типы планов
- Триальный (90 дней) - автоматически при создании
- Месячный - 30 дней
- Квартальный - 90 дней
- Годовой - 365 дней
Технические детали
Валидация schema_name
Regex: ^[a-z0-9](?:[a-z0-9\-]{0,61}[a-z0-9])?$
Правила:
- Только латинские буквы в нижнем регистре
- Цифры и дефис разрешены
- Длина 3-63 символа
- Не может начинаться или заканчиваться дефисом
- Не совпадает с зарезервированными именами
Зарезервированные имена
RESERVED_SCHEMA_NAMES = [
'public', 'admin', 'api', 'www', 'mail', 'ftp', 'smtp',
'static', 'media', 'assets', 'cdn', 'app', 'web',
'billing', 'register', 'login', 'logout', 'dashboard',
'test', 'dev', 'staging', 'production', 'demo'
]
Email для супер-админа
Один email может использоваться для нескольких магазинов (полезно для вас как супер-админа для входа в разные тенанты).
Для обычных пользователей форма проверяет наличие pending заявок с таким же email.
Что дальше (рекомендации)
1. Email-уведомления
Добавить отправку писем:
- Пользователю при активации заявки
- Пользователю при истечении подписки (за 7 дней, за 1 день)
- Админу при новой заявке
2. Биллинг
Создать страницу /billing/ где владелец магазина может:
- Посмотреть текущую подписку
- Продлить подписку
- Оплатить через платежную систему
3. Middleware для is_active
Если нужна жесткая блокировка доступа к деактивированным магазинам, создать middleware:
# tenants/middleware.py
class TenantStatusMiddleware:
def __call__(self, request):
if hasattr(request, 'tenant'):
if not request.tenant.is_active:
# Показать страницу "Магазин заблокирован"
pass
sub = request.tenant.subscription
if sub.is_expired():
# Редирект на /billing/renew/
pass
return self.get_response(request)
4. Автоматическая очистка
Создать команду для удаления старых отклоненных заявок:
python manage.py cleanup_old_registrations --days=30
Структура файлов
myproject/tenants/
├── models.py # Модели Client, TenantRegistration, Subscription
├── admin.py # Админ-панель с функционалом активации
├── forms.py # Форма регистрации с валидацией
├── views.py # Views для публичной регистрации
├── urls.py # Роуты /register/ и /register/success/
└── templates/tenants/
├── base.html # Базовый шаблон
├── registration_form.html # Форма регистрации
└── registration_success.html # Страница благодарности
Тестирование
1. Регистрация магазина
# Запустите сервер
python manage.py runserver
# Откройте браузер
http://localhost:8000/register/
# Заполните форму:
Название: Тестовый магазин
Поддомен: testshop
Имя: Иван Иванов
Email: test@example.com
Телефон: +375291234567
# Отправьте заявку
2. Активация через админку
# Войдите в админку
http://localhost:8000/admin/
# Логин/пароль супер-админа
# Перейдите в "Заявки на регистрацию"
# Нажмите "Активировать" напротив заявки
3. Проверка созданного магазина
# Откройте браузер
http://testshop.localhost:8000/
# Должна открыться страница магазина
Поддержка
При возникновении проблем проверьте:
- Миграции применены:
python manage.py migrate_schemas --shared - В
settings.pyприложениеtenantsвSHARED_APPS - В
urls_public.pyподключены роуты tenants - Виртуальное окружение активировано
phonenumber_fieldустановлен
Система готова к использованию!
Теперь вы можете:
- Принимать заявки на регистрацию
- Модерировать их через админку
- Управлять подписками
- Контролировать доступ к магазинам