update `slug` field for `Post` model using `TweakedAutoSlugField` to improve auto-slug behavior with Unicode and additional options. Add detailed `attribute_values` to demo products for enriched metadata. Update dependencies for stability and features.
132 lines
4.1 KiB
Python
132 lines
4.1 KiB
Python
from django.conf import settings
|
|
from django.db.models import (
|
|
CASCADE,
|
|
BooleanField,
|
|
CharField,
|
|
FileField,
|
|
ForeignKey,
|
|
ManyToManyField,
|
|
TextField,
|
|
)
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from engine.core.abstract import NiceModel
|
|
from engine.core.utils.db import TweakedAutoSlugField, unicode_slugify_function
|
|
|
|
|
|
class Post(NiceModel):
|
|
__doc__ = _( # pyright: ignore[reportUnknownVariableType]
|
|
"Represents a blog post model. "
|
|
"The Post class defines the structure and behavior of a blog post. "
|
|
"It includes attributes for author, title, content, optional file attachment, slug, and associated tags. "
|
|
"The class enforces constraints such as requiring either content or a file attachment but not both simultaneously. "
|
|
"It also supports automatic slug generation based on the title."
|
|
)
|
|
|
|
is_publicly_visible = True
|
|
|
|
author = ForeignKey(
|
|
to=settings.AUTH_USER_MODEL,
|
|
on_delete=CASCADE,
|
|
blank=False,
|
|
null=False,
|
|
related_name="posts",
|
|
)
|
|
title = CharField(
|
|
unique=True,
|
|
max_length=128,
|
|
blank=False,
|
|
null=False,
|
|
help_text=_("post title"),
|
|
verbose_name=_("title"),
|
|
)
|
|
content = TextField(
|
|
verbose_name=_("content"),
|
|
help_text=_("post content"),
|
|
blank=True,
|
|
null=True,
|
|
)
|
|
file = FileField(upload_to="posts/", blank=True, null=True)
|
|
slug = TweakedAutoSlugField(
|
|
populate_from="title",
|
|
slugify_function=unicode_slugify_function,
|
|
allow_unicode=True,
|
|
unique=True,
|
|
editable=False,
|
|
max_length=88,
|
|
overwrite=True,
|
|
null=True,
|
|
)
|
|
tags = ManyToManyField(to="blog.PostTag", blank=True, related_name="posts")
|
|
meta_description = CharField(max_length=150, blank=True, null=True)
|
|
is_static_page = BooleanField(
|
|
default=False,
|
|
verbose_name=_("is static page"),
|
|
help_text=_(
|
|
"is this a post for a page with static URL (e.g. `/help/delivery`)?"
|
|
),
|
|
)
|
|
|
|
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, *args, **kwargs):
|
|
if self.file:
|
|
raise ValueError(
|
|
_("file uploads are not supported yet - use content instead")
|
|
)
|
|
if not any([self.file, self.content]) or all([self.file, self.content]):
|
|
raise ValueError(
|
|
_("a file or content must be provided - mutually exclusive")
|
|
)
|
|
super().save(*args, **kwargs)
|
|
|
|
|
|
class PostTag(NiceModel):
|
|
"""
|
|
Represents a tag associated with a post.
|
|
|
|
The PostTag class is used to define and manage tags that can be assigned
|
|
to posts. These tags include an internal identifier and a user-friendly
|
|
display name. The class supports internationalization for both the internal
|
|
identifier and the display name.
|
|
|
|
Attributes:
|
|
is_publicly_visible (bool): Determines if the tag is visible publicly.
|
|
tag_name (CharField): An internal tag identifier for the post's tag. It is a required
|
|
field with a maximum length of 255 characters.
|
|
name (CharField): A user-friendly, unique display name for the post's tag
|
|
with a maximum length of 255 characters.
|
|
|
|
Meta:
|
|
verbose_name (str): Human-readable singular name of the PostTag model.
|
|
verbose_name_plural (str): Human-readable plural name of the PostTag model.
|
|
"""
|
|
|
|
is_publicly_visible = True
|
|
posts: "Post"
|
|
|
|
tag_name = CharField(
|
|
blank=False,
|
|
null=False,
|
|
max_length=255,
|
|
help_text=_("internal tag identifier for the post tag"),
|
|
verbose_name=_("tag name"),
|
|
)
|
|
name = 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")
|