| """Модели сайта: каталог, статьи, новости и сообщения.""" |
| from django.conf import settings |
| from django.db import models |
| from django.urls import reverse |
|
|
|
|
| class Category(models.Model): |
| """Категория изделий в каталоге.""" |
| title = models.CharField('Название', max_length=120) |
| slug = models.SlugField('URL', max_length=140, unique=True) |
| description = models.TextField('Описание', blank=True) |
|
|
| class Meta: |
| verbose_name = 'категория' |
| verbose_name_plural = 'категории' |
| ordering = ['title'] |
|
|
| def __str__(self): |
| return self.title |
|
|
|
|
| class Product(models.Model): |
| """Изделие из кожи.""" |
| category = models.ForeignKey(Category, verbose_name='Категория', on_delete=models.PROTECT, related_name='products') |
| title = models.CharField('Название', max_length=160) |
| slug = models.SlugField('URL', max_length=180, unique=True) |
| short_description = models.CharField('Краткое описание', max_length=260) |
| description = models.TextField('Описание') |
| price = models.DecimalField('Цена', max_digits=10, decimal_places=2) |
| image_filename = models.CharField('Файл изображения', max_length=120) |
| characteristics = models.TextField('Характеристики', blank=True) |
| is_featured = models.BooleanField('Показывать на главной', default=False) |
| created_at = models.DateTimeField('Дата добавления', auto_now_add=True) |
|
|
| class Meta: |
| verbose_name = 'изделие' |
| verbose_name_plural = 'изделия' |
| ordering = ['title'] |
|
|
| def __str__(self): |
| return self.title |
|
|
| def get_absolute_url(self): |
| return reverse('product_detail', kwargs={'slug': self.slug}) |
|
|
|
|
| class Article(models.Model): |
| """Статья информационного раздела.""" |
| title = models.CharField('Заголовок', max_length=180) |
| slug = models.SlugField('URL', max_length=200, unique=True) |
| lead = models.CharField('Аннотация', max_length=320) |
| content = models.TextField('Текст') |
| image_filename = models.CharField('Файл изображения', max_length=120, default='materials-technologies.png') |
| created_at = models.DateTimeField('Дата публикации', auto_now_add=True) |
|
|
| class Meta: |
| verbose_name = 'статья' |
| verbose_name_plural = 'статьи' |
| ordering = ['-created_at', 'title'] |
|
|
| def __str__(self): |
| return self.title |
|
|
| def get_absolute_url(self): |
| return reverse('article_detail', kwargs={'slug': self.slug}) |
|
|
|
|
| class News(models.Model): |
| """Новость мастерской.""" |
| title = models.CharField('Заголовок', max_length=180) |
| slug = models.SlugField('URL', max_length=200, unique=True) |
| lead = models.CharField('Аннотация', max_length=320) |
| content = models.TextField('Текст') |
| image_filename = models.CharField('Файл изображения', max_length=120, default='hero-leather-workshop.png') |
| published_at = models.DateTimeField('Дата публикации') |
|
|
| class Meta: |
| verbose_name = 'новость' |
| verbose_name_plural = 'новости' |
| ordering = ['-published_at', 'title'] |
|
|
| def __str__(self): |
| return self.title |
|
|
| def get_absolute_url(self): |
| return reverse('news_detail', kwargs={'slug': self.slug}) |
|
|
|
|
| class ContactMessage(models.Model): |
| """Обращение пользователя из формы обратной связи.""" |
| STATUS_CHOICES = [('new', 'Новое'), ('processing', 'В работе'), ('closed', 'Закрыто')] |
| user = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name='Пользователь', null=True, blank=True, on_delete=models.SET_NULL) |
| name = models.CharField('Имя', max_length=120) |
| email = models.EmailField('Email') |
| subject = models.CharField('Тема', max_length=180) |
| text = models.TextField('Сообщение') |
| status = models.CharField('Статус', max_length=20, choices=STATUS_CHOICES, default='new') |
| created_at = models.DateTimeField('Дата отправки', auto_now_add=True) |
|
|
| class Meta: |
| verbose_name = 'сообщение' |
| verbose_name_plural = 'сообщения' |
| ordering = ['-created_at'] |
|
|
| def __str__(self): |
| return f'{self.subject} — {self.email}' |
|
|