Реализован полный CRUD для тегов товаров
Упрощена модель ProductTag: - Удалены поля soft delete (is_deleted, deleted_at, deleted_by) - Добавлено поле is_active для управления статусом - Упрощены менеджеры и методы модели Создан CRUD функционал: - ProductTagForm: форма с автогенерацией slug - Views: список, создание, просмотр, редактирование, удаление - URL маршруты: /products/tags/* - Шаблоны: list, form, detail, confirm_delete Особенности: - Поиск по названию и slug - Фильтрация по статусу активности - Статистика использования тегов в товарах/комплектах - Пагинация (20 на страницу) - Предупреждение при удалении с отображением связанных объектов - Добавлена ссылка "Теги" в навигацию 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -451,3 +451,40 @@ ProductVariantGroupItemFormSetUpdate = inlineformset_factory(
|
||||
validate_min=False, # Не требовать минимум товаров
|
||||
can_delete_extra=True, # Разрешить удалять дополнительные формы
|
||||
)
|
||||
|
||||
|
||||
class ProductTagForm(forms.ModelForm):
|
||||
"""
|
||||
Форма для создания и редактирования тегов товаров.
|
||||
"""
|
||||
class Meta:
|
||||
model = ProductTag
|
||||
fields = ['name', 'slug', 'is_active']
|
||||
labels = {
|
||||
'name': 'Название',
|
||||
'slug': 'URL-идентификатор',
|
||||
'is_active': 'Активен'
|
||||
}
|
||||
help_texts = {
|
||||
'slug': 'Оставьте пустым для автоматической генерации из названия',
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['name'].widget.attrs.update({
|
||||
'class': 'form-control form-control-lg fw-semibold',
|
||||
'placeholder': 'Введите название тега'
|
||||
})
|
||||
self.fields['slug'].widget.attrs.update({
|
||||
'class': 'form-control',
|
||||
'placeholder': 'url-identifier (автоматически)'
|
||||
})
|
||||
self.fields['slug'].required = False
|
||||
self.fields['is_active'].widget.attrs.update({'class': 'form-check-input'})
|
||||
|
||||
def clean_slug(self):
|
||||
"""Разрешаем пустой slug - он сгенерируется в модели"""
|
||||
slug = self.cleaned_data.get('slug')
|
||||
if slug == '' or slug is None:
|
||||
return None
|
||||
return slug
|
||||
|
||||
Reference in New Issue
Block a user