schon/engine/core/serializers/simple.py
Egor fureunoir Gorbunov eef774c3a3 feat(markdown): integrate markdown rendering and editor support
Replace WYSIWYG editor with Markdown editor across all relevant models and admin fields. Add utilities for rendering and stripping markdown. Adjust serializers, views, and templates to support markdown content. Introduce `PastedImage` model and upload endpoint for handling inline image uploads in markdown.

This change simplifies content formatting while enhancing flexibility with markdown support.
2026-02-27 23:36:51 +03:00

309 lines
7.6 KiB
Python

from typing import Any
from rest_framework.fields import JSONField, SerializerMethodField
from rest_framework.relations import PrimaryKeyRelatedField
from rest_framework.serializers import ModelSerializer
from engine.core.models import (
Attribute,
AttributeGroup,
AttributeValue,
Brand,
Category,
Feedback,
Order,
OrderProduct,
Product,
ProductImage,
ProductTag,
PromoCode,
Promotion,
Stock,
Vendor,
Wishlist,
)
from engine.core.serializers.utility import AddressSerializer
from engine.core.utils.markdown import render_markdown
class AttributeGroupSimpleSerializer(ModelSerializer):
parent = PrimaryKeyRelatedField(read_only=True)
children = PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = AttributeGroup
fields = [
"uuid",
"name",
"parent",
"children",
]
class CategorySimpleSerializer(ModelSerializer):
children = SerializerMethodField()
class Meta:
model = Category
fields = [
"uuid",
"name",
"image",
"slug",
"children",
]
def get_children(self, obj: Category) -> list[dict[str, Any]]:
request = self.context.get("request")
if request is not None and request.user.has_perm("view_category"):
children = obj.children.all()
else:
children = obj.children.filter(is_active=True)
if obj.children.exists():
serializer = CategorySimpleSerializer(
children, many=True, context=self.context
)
return list(serializer.data)
return []
class BrandSimpleSerializer(ModelSerializer):
class Meta:
model = Brand
fields = [
"uuid",
"name",
"small_logo",
"big_logo",
]
class ProductTagSimpleSerializer(ModelSerializer):
class Meta:
model = ProductTag
fields = [
"uuid",
"tag_name",
"name",
]
class ProductImageSimpleSerializer(ModelSerializer):
product: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True)
class Meta:
model = ProductImage
fields = [
"uuid",
"alt",
"image",
"priority",
"product",
]
class AttributeSimpleSerializer(ModelSerializer):
group = AttributeGroupSimpleSerializer(read_only=True)
class Meta:
model = Attribute
fields = [
"uuid",
"name",
"value_type",
"group",
]
class AttributeValueSimpleSerializer(ModelSerializer):
attribute = AttributeSimpleSerializer(read_only=True)
product: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True)
class Meta:
model = AttributeValue
fields = [
"uuid",
"value",
"attribute",
"product",
]
class ProductSimpleSerializer(ModelSerializer):
brand = BrandSimpleSerializer(read_only=True)
category = CategorySimpleSerializer(read_only=True)
tags = ProductTagSimpleSerializer(many=True, read_only=True)
images = ProductImageSimpleSerializer(many=True, read_only=True)
attributes = AttributeValueSimpleSerializer(many=True, read_only=True)
description = SerializerMethodField()
rating = SerializerMethodField()
price = SerializerMethodField()
quantity = SerializerMethodField()
feedbacks_count = SerializerMethodField()
personal_orders_only = SerializerMethodField()
discount_price = SerializerMethodField()
class Meta:
model = Product
fields = [
"uuid",
"name",
"sku",
"is_digital",
"slug",
"description",
"partnumber",
"brand",
"feedbacks_count",
"personal_orders_only",
"category",
"tags",
"images",
"attributes",
"rating",
"price",
"quantity",
"discount_price",
]
def get_description(self, obj: Product) -> str:
return render_markdown(obj.description or "")
def get_rating(self, obj: Product) -> float:
return obj.rating
def get_price(self, obj: Product) -> float:
return obj.price
def get_feedbacks_count(self, obj: Product) -> int:
return obj.feedbacks_count
def get_quantity(self, obj: Product) -> int:
return obj.quantity
def get_personal_orders_only(self, obj: Product) -> bool:
return obj.personal_orders_only
def get_discount_price(self, obj: Product) -> float | None:
return obj.discount_price
class VendorSimpleSerializer(ModelSerializer):
class Meta:
model = Vendor
fields = [
"uuid",
"name",
]
class StockSimpleSerializer(ModelSerializer):
vendor = VendorSimpleSerializer(read_only=True)
product = ProductSimpleSerializer(read_only=True)
class Meta:
model = Stock
fields = [
"uuid",
"price",
"purchase_price",
"quantity",
"sku",
"vendor",
"product",
]
class PromoCodeSimpleSerializer(ModelSerializer):
class Meta:
model = PromoCode
fields = [
"uuid",
"code",
]
class PromotionSimpleSerializer(ModelSerializer):
products = ProductSimpleSerializer(many=True, read_only=True)
class Meta:
model = Promotion
fields = [
"uuid",
"name",
"discount_percent",
"products",
]
class WishlistSimpleSerializer(ModelSerializer):
user: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True)
products = ProductSimpleSerializer(many=True, read_only=True)
class Meta:
model = Wishlist
fields = [
"uuid",
"user",
"products",
]
class FeedbackSimpleSerializer(ModelSerializer):
order_product: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True)
class Meta:
model = Feedback
fields = [
"uuid",
"rating",
"order_product",
]
class OrderProductSimpleSerializer(ModelSerializer):
product = ProductSimpleSerializer(read_only=True)
class Meta:
model = OrderProduct
fields = [
"uuid",
"product",
"quantity",
"buy_price",
"status",
]
class OrderSimpleSerializer(ModelSerializer):
user: PrimaryKeyRelatedField = PrimaryKeyRelatedField(read_only=True)
promo_code = PromoCodeSimpleSerializer(read_only=True)
order_products = OrderProductSimpleSerializer(many=True, read_only=True)
billing_address = AddressSerializer(read_only=True, required=False)
shipping_address = AddressSerializer(read_only=True, required=False)
attributes = JSONField(required=False)
total_price = SerializerMethodField(read_only=True)
class Meta:
model = Order
fields = [
"uuid",
"human_readable_id",
"billing_address",
"shipping_address",
"attributes",
"status",
"user",
"total_price",
"promo_code",
"order_products",
"buy_time",
"created",
"modified",
]
def get_total_price(self, obj: Order) -> float:
return obj.total_price