from django.conf import settings from django.db import models from django.urls import reverse from django.utils import timezone from django.utils.text import slugify from core.models import TimeStampedModel, UUIDPrimaryKeyModel class Post(UUIDPrimaryKeyModel, TimeStampedModel): title = models.CharField(max_length=200) slug = models.SlugField(max_length=220, unique=True) excerpt = models.TextField(blank=True) body = models.TextField() is_published = models.BooleanField(default=False) published_at = models.DateTimeField(null=True, blank=True) author = models.ForeignKey( settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL, related_name="blog_posts", ) class Meta: ordering = ["-published_at", "-created_at"] def __str__(self) -> str: return self.title def get_absolute_url(self) -> str: return reverse("blog:detail", kwargs={"slug": self.slug}) def save(self, *args, **kwargs): if not self.slug: base = slugify(self.title)[:200] or "post" slug = base n = 2 while Post.objects.filter(slug=slug).exclude(pk=self.pk).exists(): slug = f"{base}-{n}" n += 1 self.slug = slug if self.is_published and self.published_at is None: self.published_at = timezone.now() super().save(*args, **kwargs)