93 lines
3.6 KiB
Python
93 lines
3.6 KiB
Python
from django.db import models
|
||
from django.urls import reverse
|
||
from django.utils import timezone
|
||
from django.contrib.auth import get_user_model
|
||
from taggit.managers import TaggableManager
|
||
|
||
User = get_user_model()
|
||
|
||
class Category(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 Article(models.Model):
|
||
"""Статья блога"""
|
||
tags = TaggableManager(blank=True, verbose_name="Теги")
|
||
title = models.CharField(max_length=200, verbose_name="Заголовок")
|
||
slug = models.SlugField(max_length=220, unique=True, verbose_name="URL")
|
||
category = models.ForeignKey(
|
||
Category, on_delete=models.PROTECT, related_name="articles",
|
||
verbose_name="Категория"
|
||
)
|
||
author = models.ForeignKey(
|
||
User, on_delete=models.SET_NULL, null=True, blank=True,
|
||
verbose_name="Автор"
|
||
)
|
||
content = models.TextField(verbose_name="Содержание")
|
||
image = models.ImageField(
|
||
upload_to="blog/%Y/%m/%d/", blank=True, verbose_name="Изображение"
|
||
)
|
||
views_count = models.PositiveIntegerField(default=0, 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("blog:article_detail", kwargs={"slug": self.slug})
|
||
|
||
def get_seo_title(self):
|
||
return f"{self.title} | Блог программиста 1С"
|
||
|
||
def get_seo_description(self):
|
||
if self.meta_description:
|
||
return self.meta_description
|
||
clean = self.content[:160].replace("\n", " ").strip()
|
||
return f"{clean}..."
|
||
|
||
class Comment(models.Model):
|
||
"""Комментарий к статье"""
|
||
article = models.ForeignKey(
|
||
Article, on_delete=models.CASCADE, related_name="comments",
|
||
verbose_name="Статья"
|
||
)
|
||
author_name = models.CharField(max_length=100, verbose_name="Имя")
|
||
author_email = models.EmailField(verbose_name="Email")
|
||
content = models.TextField(verbose_name="Комментарий")
|
||
is_moderated = models.BooleanField(default=False, verbose_name="Промодерировано")
|
||
time_create = models.DateTimeField(auto_now_add=True, verbose_name="Дата создания")
|
||
|
||
class Meta:
|
||
verbose_name = "Комментарий"
|
||
verbose_name_plural = "Комментарии"
|
||
ordering = ["time_create"]
|
||
|
||
def __str__(self):
|
||
return f"{self.author_name} - {self.article.title}"
|
||
|
||
|