|
|
|
|
@ -12,15 +12,29 @@ from mptt import ( |
|
|
|
|
from mptt.models import MPTTModel, TreeForeignKey |
|
|
|
|
from autoslug import AutoSlugField |
|
|
|
|
|
|
|
|
|
from core.models import AbstractStatusModel, AbstractDateTimeModel, STATUS_ACTIVE, STATUS_DELETED, ActualOnlyManager |
|
|
|
|
from core.models import AbstractStatusModel, ActualOnlyManager, AbstractDateTimeModel |
|
|
|
|
|
|
|
|
|
# --------------------------------- PRODUCT ATTRIBUTE ------------------------------------# |
|
|
|
|
# ---------------------------------- COMMON PRODUCT STATUS ---------------------------------------# |
|
|
|
|
# Create your models here. |
|
|
|
|
STATUS_INACTIVE = 0 |
|
|
|
|
STATUS_ACTIVE = 25 |
|
|
|
|
STATUS_DELETED = 50 |
|
|
|
|
|
|
|
|
|
STATUS_DEFAULT = STATUS_ACTIVE |
|
|
|
|
|
|
|
|
|
STATUS_CHOICES = ( |
|
|
|
|
(STATUS_INACTIVE, _('Неактивный')), |
|
|
|
|
(STATUS_ACTIVE, _('Активный')), |
|
|
|
|
(STATUS_DELETED, _('Удаленный')), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
# --------------------------------- PRODUCT ATTRIBUTE STATTUS------------------------------------# |
|
|
|
|
PRODUCT_ATTRIBUTE_TYPE_NONE = 0 |
|
|
|
|
PRODUCT_ATTRIBUTE_TYPE_RANGE = 50 |
|
|
|
|
PRODUCT_ATTRIBUTE_TYPE_SELECT = 100 |
|
|
|
|
|
|
|
|
|
PRODUCT_ATTRIBUTE_TYPE_CHOICES = ( |
|
|
|
|
(PRODUCT_ATTRIBUTE_TYPE_NONE, _('никакой')), |
|
|
|
|
(PRODUCT_ATTRIBUTE_TYPE_NONE, _('отсуствует')), |
|
|
|
|
(PRODUCT_ATTRIBUTE_TYPE_RANGE, _('диапазон')), |
|
|
|
|
(PRODUCT_ATTRIBUTE_TYPE_SELECT, _('выбор')) |
|
|
|
|
) |
|
|
|
|
@ -44,6 +58,7 @@ class ProductAttribute(AbstractStatusModel): |
|
|
|
|
type = models.SmallIntegerField(_('тип'), choices=PRODUCT_ATTRIBUTE_TYPE_CHOICES, |
|
|
|
|
default=PRODUCT_ATTRIBUTE_TYPE_DEFAULT) |
|
|
|
|
main_attribute = models.BooleanField(default=False) |
|
|
|
|
status = models.SmallIntegerField(_('статус'), default=STATUS_DEFAULT, choices=STATUS_CHOICES) |
|
|
|
|
|
|
|
|
|
objects = ProductAttributeManager() |
|
|
|
|
|
|
|
|
|
@ -78,11 +93,12 @@ class ProductCategoryManager(mptt_managers.TreeManager, ActualOnlyManager): |
|
|
|
|
return self.get_queryset().all() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ProductCategory(MPTTModel, AbstractDateTimeModel): |
|
|
|
|
class ProductCategory(MPTTModel, AbstractStatusModel): |
|
|
|
|
name = models.CharField(db_index=True, unique=True, max_length=64, blank=True, null=True, default=None) |
|
|
|
|
slug = AutoSlugField(populate_from='name') |
|
|
|
|
parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children') |
|
|
|
|
image = models.ImageField(upload_to='categories', blank=True, verbose_name="image of category") |
|
|
|
|
status = models.SmallIntegerField(_('статус'), default=STATUS_DEFAULT, choices=STATUS_CHOICES) |
|
|
|
|
|
|
|
|
|
objects = ProductCategoryManager() |
|
|
|
|
|
|
|
|
|
@ -109,6 +125,7 @@ class Product(AbstractStatusModel): |
|
|
|
|
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.SET_NULL, blank=True, null=True) |
|
|
|
|
category = models.ForeignKey(ProductCategory, on_delete=models.SET_NULL, blank=True, null=True) |
|
|
|
|
attributes = models.ManyToManyField(ProductAttribute, blank=True) |
|
|
|
|
status = models.SmallIntegerField(_('статус'), default=STATUS_DEFAULT, choices=STATUS_CHOICES) |
|
|
|
|
|
|
|
|
|
def __str__(self): |
|
|
|
|
return self.name |
|
|
|
|
@ -137,7 +154,7 @@ class Product(AbstractStatusModel): |
|
|
|
|
# pp.save() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ProductRate(AbstractStatusModel): |
|
|
|
|
class ProductRate(AbstractDateTimeModel): |
|
|
|
|
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) |
|
|
|
|
product = models.ForeignKey(Product, on_delete=models.CASCADE) |
|
|
|
|
rate = models.IntegerField(_('оценка'), default=0) |
|
|
|
|
@ -150,7 +167,7 @@ class ProductRate(AbstractStatusModel): |
|
|
|
|
class ProductDiscount(AbstractStatusModel): |
|
|
|
|
product = models.ForeignKey(Product, on_delete=models.CASCADE) |
|
|
|
|
percentage = models.DecimalField(_('процент'), max_digits=3, decimal_places=2) |
|
|
|
|
status = models.BooleanField(_('статус'), default=False) |
|
|
|
|
status = models.BooleanField(_('статус'), choices=STATUS_CHOICES, default=STATUS_DEFAULT) |
|
|
|
|
|
|
|
|
|
class Meta: |
|
|
|
|
verbose_name = _('Дисконт') |
|
|
|
|
@ -173,14 +190,6 @@ class ProductAttributeValue(AbstractStatusModel): |
|
|
|
|
|
|
|
|
|
# ----------------- PRODUCT IMAGE STATUS LIST ------------------ |
|
|
|
|
|
|
|
|
|
PRODUCT_IMAGE_STATUS_CHOICES = ( |
|
|
|
|
(STATUS_ACTIVE, _('Активный')), |
|
|
|
|
(STATUS_DELETED, _('Удален')), |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
PRODUCT_IMAGE_DEFAULT_STATUS = STATUS_ACTIVE |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ProductImage(AbstractStatusModel): |
|
|
|
|
def get_file_path(self, filename): |
|
|
|
|
return "products/attachments/{product}/{filename}".format(**{ |
|
|
|
|
@ -189,8 +198,8 @@ class ProductImage(AbstractStatusModel): |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
product = models.ForeignKey(Product, on_delete=models.CASCADE) |
|
|
|
|
status = models.SmallIntegerField(_('Статус'), default=PRODUCT_IMAGE_DEFAULT_STATUS, |
|
|
|
|
choices=PRODUCT_IMAGE_STATUS_CHOICES) |
|
|
|
|
status = models.SmallIntegerField(_('Статус'),choices=STATUS_CHOICES, default=STATUS_DEFAULT, |
|
|
|
|
) |
|
|
|
|
filename = models.CharField(_('Имя файла'), max_length=255) |
|
|
|
|
image = models.FileField(_('Изображение'), upload_to=get_file_path, max_length=500) |
|
|
|
|
is_default = models.BooleanField(_('По умолчанию'), default=False) |
|
|
|
|
|