""" Модели для справочника атрибутов товаров. Используется для создания переиспользуемых атрибутов (Длина стебля, Цвет, Размер и т.д.) """ from django.db import models from django.utils.text import slugify from unidecode import unidecode class ProductAttribute(models.Model): """ Справочник атрибутов для вариативных товаров. Примеры: Длина стебля, Цвет, Размер, Упаковка. """ name = models.CharField( max_length=100, unique=True, verbose_name="Название", help_text="Например: Длина стебля, Цвет, Размер" ) slug = models.SlugField( max_length=100, unique=True, blank=True, verbose_name="Slug", help_text="Автоматически генерируется из названия" ) description = models.TextField( blank=True, verbose_name="Описание", help_text="Опциональное описание атрибута" ) position = models.PositiveIntegerField( default=0, verbose_name="Позиция", help_text="Порядок отображения в списке" ) created_at = models.DateTimeField( auto_now_add=True, verbose_name="Дата создания" ) updated_at = models.DateTimeField( auto_now=True, verbose_name="Дата обновления" ) class Meta: verbose_name = "Атрибут товара" verbose_name_plural = "Атрибуты товаров" ordering = ['position', 'name'] def __str__(self): return self.name def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(unidecode(self.name)) super().save(*args, **kwargs) @property def values_count(self): """Количество значений у атрибута""" return self.values.count() class ProductAttributeValue(models.Model): """ Значения атрибутов. Примеры для атрибута "Длина стебля": 50, 60, 70, 80. """ attribute = models.ForeignKey( ProductAttribute, on_delete=models.CASCADE, related_name='values', verbose_name="Атрибут" ) value = models.CharField( max_length=100, verbose_name="Значение", help_text="Например: 50, 60, 70 (для длины) или Красный, Белый (для цвета)" ) slug = models.SlugField( max_length=100, blank=True, verbose_name="Slug" ) position = models.PositiveIntegerField( default=0, verbose_name="Позиция", help_text="Порядок отображения в списке значений" ) created_at = models.DateTimeField( auto_now_add=True, verbose_name="Дата создания" ) updated_at = models.DateTimeField( auto_now=True, verbose_name="Дата обновления" ) class Meta: verbose_name = "Значение атрибута" verbose_name_plural = "Значения атрибутов" ordering = ['position', 'value'] unique_together = ['attribute', 'value'] indexes = [ models.Index(fields=['attribute', 'position']), ] def __str__(self): return f"{self.attribute.name}: {self.value}" def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(unidecode(self.value)) super().save(*args, **kwargs)