Files
octopus/myproject/tenants/forms.py

116 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
from django import forms
from django.core.exceptions import ValidationError
from .models import TenantRegistration, Client, RESERVED_SCHEMA_NAMES
class TenantRegistrationForm(forms.ModelForm):
"""
Форма регистрации нового тенанта
"""
class Meta:
model = TenantRegistration
fields = ['shop_name', 'schema_name', 'owner_name', 'owner_email', 'phone']
widgets = {
'shop_name': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Название вашего магазина',
'required': True
}),
'schema_name': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'myshop',
'required': True,
'pattern': '[a-z0-9][a-z0-9\-]{1,61}[a-z0-9]',
'title': 'Только латинские буквы в нижнем регистре, цифры и дефис (3-63 символа)'
}),
'owner_name': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Иван Иванов',
'required': True
}),
'owner_email': forms.EmailInput(attrs={
'class': 'form-control',
'placeholder': 'your@email.com',
'required': True
}),
'phone': forms.TextInput(attrs={
'class': 'form-control',
'placeholder': '+375291234567',
'required': True
}),
}
labels = {
'shop_name': 'Название магазина',
'schema_name': 'Желаемый поддомен',
'owner_name': 'Ваше имя',
'owner_email': 'Email',
'phone': 'Телефон',
}
help_texts = {
'schema_name': 'Будет использоваться как поддомен: yourshop.flowers. '
'Только латинские буквы, цифры и дефис (3-63 символа)',
'owner_email': 'Это email владельца будущего аккаунта, на этот email придет уведомление об активации',
}
def clean_schema_name(self):
"""
Валидация поддомена:
1. Приводим к нижнему регистру
2. Проверяем длину
3. Проверяем, что не зарезервировано
4. Проверяем уникальность
"""
schema_name = self.cleaned_data.get('schema_name', '').lower().strip()
# Проверка длины
if len(schema_name) < 3:
raise ValidationError("Поддомен должен содержать минимум 3 символа.")
if len(schema_name) > 63:
raise ValidationError("Поддомен не может быть длиннее 63 символов.")
# Проверка на зарезервированные имена
if schema_name in RESERVED_SCHEMA_NAMES:
raise ValidationError(f"Поддомен '{schema_name}' зарезервирован системой. Выберите другой.")
# Проверка уникальности в заявках
if TenantRegistration.objects.filter(schema_name=schema_name).exists():
raise ValidationError(f"Поддомен '{schema_name}' уже занят. Выберите другой.")
# Проверка уникальности в существующих тенантах
if Client.objects.filter(schema_name=schema_name).exists():
raise ValidationError(f"Поддомен '{schema_name}' уже занят. Выберите другой.")
return schema_name
def clean_owner_email(self):
"""
Валидация email: проверка на дубликаты для обычных пользователей
(супер-админ может иметь несколько тенантов)
"""
email = self.cleaned_data.get('owner_email', '').lower().strip()
# Проверяем, есть ли активные заявки с таким email
pending_registrations = TenantRegistration.objects.filter(
owner_email=email,
status=TenantRegistration.STATUS_PENDING
).count()
if pending_registrations > 0:
raise ValidationError(
f"У вас уже есть заявка на регистрацию с email {email}, ожидающая проверки. "
"Дождитесь активации или свяжитесь с поддержкой."
)
# Проверяем количество существующих тенантов с таким email
# Если больше 0 - это нормально для админов, но для обычных пользователей показываем предупреждение
existing_tenants_count = Client.objects.filter(owner_email=email).count()
if existing_tenants_count > 0:
# Добавляем предупреждение, но не блокируем (на случай если это супер-админ)
# В реальности здесь можно добавить более сложную логику
pass
return email