131 lines
5.1 KiB
Python
131 lines
5.1 KiB
Python
from django.db import models
|
||
from django.urls import reverse
|
||
from django.utils.html import strip_tags
|
||
from django.conf import settings
|
||
import re
|
||
|
||
|
||
class ProductCategory(models.Model):
|
||
"""Категория продуктов"""
|
||
name = models.CharField(max_length=100, unique=True, verbose_name="Название")
|
||
slug = models.SlugField(max_length=120, unique=True, verbose_name="URL")
|
||
description = models.TextField(blank=True, verbose_name="Описание")
|
||
|
||
class Meta:
|
||
verbose_name = "Категория продуктов"
|
||
verbose_name_plural = "Категории продуктов"
|
||
|
||
def __str__(self):
|
||
return self.name
|
||
|
||
|
||
class Configuration(models.Model):
|
||
"""Конфигурация 1С, к которой относится продукт"""
|
||
name = models.CharField(max_length=200, unique=True, verbose_name="Название")
|
||
slug = models.SlugField(max_length=220, unique=True, verbose_name="URL")
|
||
description = models.TextField(blank=True, verbose_name="Описание")
|
||
|
||
class Meta:
|
||
verbose_name = "Конфигурация 1С"
|
||
verbose_name_plural = "Конфигурации 1С"
|
||
|
||
def __str__(self):
|
||
return self.name
|
||
|
||
|
||
class Product(models.Model):
|
||
"""Программный продукт / модуль 1С"""
|
||
title = models.CharField(max_length=200, verbose_name="Название")
|
||
slug = models.SlugField(max_length=220, unique=True, verbose_name="URL")
|
||
category = models.ForeignKey(
|
||
ProductCategory,
|
||
on_delete=models.PROTECT,
|
||
related_name="products",
|
||
verbose_name="Категория"
|
||
)
|
||
short_description = models.TextField(
|
||
verbose_name="Краткое описание",
|
||
help_text="Отображается в списке продуктов"
|
||
)
|
||
content = models.TextField(verbose_name="Полное описание")
|
||
price = models.DecimalField(
|
||
max_digits=10,
|
||
decimal_places=2,
|
||
verbose_name="Цена",
|
||
help_text="Будет видна только зарегистрированным пользователям"
|
||
)
|
||
image = models.ImageField(
|
||
upload_to="products/%Y/%m/%d/",
|
||
blank=True,
|
||
verbose_name="Изображение"
|
||
)
|
||
configurations = models.ManyToManyField(
|
||
Configuration,
|
||
blank=True,
|
||
related_name="products",
|
||
verbose_name="Совместимые конфигурации"
|
||
)
|
||
is_published = models.BooleanField(default=True, verbose_name="Опубликовано")
|
||
time_create = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")
|
||
time_update = models.DateTimeField(auto_now=True, verbose_name="Дата изменения")
|
||
meta_description = models.CharField(
|
||
max_length=160,
|
||
blank=True,
|
||
verbose_name="Meta-описание",
|
||
help_text="Краткое описание для поисковых систем (до 160 символов)"
|
||
)
|
||
|
||
class Meta:
|
||
verbose_name = "Продукт"
|
||
verbose_name_plural = "Продукты"
|
||
ordering = ["-time_create"]
|
||
indexes = [
|
||
models.Index(fields=["-time_create", "is_published"]),
|
||
]
|
||
|
||
def __str__(self):
|
||
return self.title
|
||
|
||
def get_absolute_url(self):
|
||
return reverse("products:product_detail", kwargs={"slug": self.slug})
|
||
|
||
def get_seo_title(self):
|
||
return f"{self.title} | Продукты С.Н.А. Технологии"
|
||
|
||
def get_seo_description(self):
|
||
if self.meta_description:
|
||
return self.meta_description
|
||
clean = re.sub(r'\s+', ' ', strip_tags(self.short_description)).strip()
|
||
return clean[:157] + '…' if len(clean) > 160 else clean
|
||
|
||
|
||
class Order(models.Model):
|
||
product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name='Продукт')
|
||
configuration = models.ForeignKey(
|
||
Configuration,
|
||
on_delete=models.SET_NULL,
|
||
null=True, blank=True,
|
||
verbose_name='Конфигурация 1С'
|
||
)
|
||
user = models.ForeignKey(
|
||
settings.AUTH_USER_MODEL,
|
||
on_delete=models.SET_NULL,
|
||
null=True, blank=True,
|
||
verbose_name='Пользователь'
|
||
)
|
||
name = models.CharField(max_length=100, verbose_name='Имя')
|
||
phone = models.CharField(max_length=20, verbose_name='Телефон')
|
||
email = models.EmailField(verbose_name='Email')
|
||
address = models.TextField(blank=True, verbose_name='Адрес доставки')
|
||
comment = models.TextField(blank=True, verbose_name='Комментарий')
|
||
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Дата заказа')
|
||
is_processed = models.BooleanField(default=False, verbose_name='Обработан')
|
||
notification_sent = models.BooleanField(default=False, verbose_name='Уведомление отправлено')
|
||
|
||
class Meta:
|
||
verbose_name = 'Заказ'
|
||
verbose_name_plural = 'Заказы'
|
||
ordering = ['-created_at']
|
||
|
||
def __str__(self):
|
||
return f'Заказ #{self.id} – {self.product.title} от {self.name}' |