from django.db.models import CASCADE, CharField, FileField, ForeignKey, ManyToManyField from django.utils.translation import gettext_lazy as _ from django_extensions.db.fields import AutoSlugField from markdown.extensions.toc import TocExtension from markdown_field import MarkdownField from core.abstract import NiceModel class Post(NiceModel): is_publicly_visible = True author: ForeignKey = ForeignKey( to="vibes_auth.User", on_delete=CASCADE, blank=False, null=False, related_name="posts" ) title: CharField = CharField( unique=True, max_length=128, blank=False, null=False, help_text=_("post title"), verbose_name=_("title") ) content: MarkdownField = MarkdownField( "content", extensions=[ TocExtension(toc_depth=3), "pymdownx.arithmatex", "pymdownx.b64", "pymdownx.betterem", "pymdownx.blocks.admonition", "pymdownx.blocks.caption", "pymdownx.blocks.definition", "pymdownx.blocks.details", "pymdownx.blocks.html", "pymdownx.blocks.tab", "pymdownx.caret", "pymdownx.critic", "pymdownx.emoji", "pymdownx.escapeall", "pymdownx.extra", "pymdownx.fancylists", "pymdownx.highlight", "pymdownx.inlinehilite", "pymdownx.keys", "pymdownx.magiclink", "pymdownx.mark", "pymdownx.pathconverter", "pymdownx.progressbar", "pymdownx.saneheaders", "pymdownx.smartsymbols", "pymdownx.snippets", "pymdownx.striphtml", "pymdownx.superfences", "pymdownx.tasklist", "pymdownx.tilde", ], blank=True, null=True, ) file: FileField = FileField(upload_to="posts/", blank=True, null=True) slug: AutoSlugField = AutoSlugField(populate_from="title", allow_unicode=True, unique=True, editable=False) tags: ManyToManyField = ManyToManyField(to="blog.PostTag", blank=True, related_name="posts") def __str__(self): return f"{self.title} | {self.author.first_name} {self.author.last_name}" class Meta: verbose_name = _("post") verbose_name_plural = _("posts") def save(self, **kwargs): if self.file: raise ValueError(_("markdown files are not supported yet - use markdown content instead")) if not any([self.file, self.content]) or all([self.file, self.content]): raise ValueError(_("a markdown file or markdown content must be provided - mutually exclusive")) super().save(**kwargs) class PostTag(NiceModel): is_publicly_visible = True tag_name: CharField = CharField( blank=False, null=False, max_length=255, help_text=_("internal tag identifier for the post tag"), verbose_name=_("tag name"), ) name: CharField = CharField( max_length=255, help_text=_("user-friendly name for the post tag"), verbose_name=_("tag display name"), unique=True, ) def __str__(self): return self.tag_name class Meta: verbose_name = _("post tag") verbose_name_plural = _("post tags")