Добавлена функциональность системного клиента для анонимных покупок
- Добавлено поле is_system_customer в модель Customer с индексом - Системный клиент создается автоматически при создании нового тенанта - Реализована защита системного клиента от редактирования и удаления: - Защита на уровне модели (save/delete методы) - Защита на уровне формы (валидация) - Защита на уровне представлений (проверки с дружественными сообщениями) - Защита в админке (readonly поля, запрет удаления) - Системный клиент скрыт из списков и поиска на фронтенде - Создан информационный шаблон для отображения системного клиента - Исправлена обработка NULL значений для полей email/phone (Django best practice) - Добавлено отображение "Не указано" вместо None в карточке клиента 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ class CustomerForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Customer
|
||||
fields = ['name', 'email', 'phone', 'loyalty_tier', 'notes']
|
||||
exclude = ['is_system_customer']
|
||||
widgets = {
|
||||
'notes': forms.Textarea(attrs={'rows': 3}),
|
||||
}
|
||||
@@ -43,9 +44,9 @@ class CustomerForm(forms.ModelForm):
|
||||
"""Проверяет уникальность email при создании/редактировании"""
|
||||
email = self.cleaned_data.get('email')
|
||||
|
||||
# Если email пустой, это нормально (blank=True)
|
||||
# Нормализуем пустые значения в None (Django best practice для nullable полей)
|
||||
if not email:
|
||||
return email
|
||||
return None
|
||||
|
||||
# Проверяем уникальность
|
||||
queryset = Customer.objects.filter(email=email)
|
||||
@@ -63,9 +64,9 @@ class CustomerForm(forms.ModelForm):
|
||||
"""Проверяет уникальность телефона при создании/редактировании"""
|
||||
phone = self.cleaned_data.get('phone')
|
||||
|
||||
# Если телефон пустой, это нормально (blank=True)
|
||||
# Нормализуем пустые значения в None (Django best practice для nullable полей)
|
||||
if not phone:
|
||||
return phone
|
||||
return None
|
||||
|
||||
# Проверяем уникальность
|
||||
queryset = Customer.objects.filter(phone=phone)
|
||||
@@ -77,4 +78,17 @@ class CustomerForm(forms.ModelForm):
|
||||
if queryset.exists():
|
||||
raise ValidationError('Клиент с таким номером телефона уже существует.')
|
||||
|
||||
return phone
|
||||
return phone
|
||||
|
||||
def clean(self):
|
||||
"""Дополнительная валидация формы"""
|
||||
cleaned_data = super().clean()
|
||||
|
||||
# Защита от редактирования системного клиента
|
||||
if self.instance and self.instance.pk and self.instance.is_system_customer:
|
||||
raise ValidationError(
|
||||
'Системный клиент не может быть изменен. '
|
||||
'Он необходим для корректной работы системы и создается автоматически.'
|
||||
)
|
||||
|
||||
return cleaned_data
|
||||
Reference in New Issue
Block a user