Introduce a unique, auto-generated slug field to the Product model, populated from category, brand, and name. Update core filters, serializers, sitemaps, and GraphQL object types to support the new slug functionality. Also, enforce HTTP-only cookies for session, CSRF, and language for improved security.
299 lines
6.9 KiB
Python
299 lines
6.9 KiB
Python
from contextlib import suppress
|
|
from typing import Optional
|
|
|
|
from rest_framework.fields import SerializerMethodField
|
|
from rest_framework.relations import PrimaryKeyRelatedField
|
|
from rest_framework.serializers import ModelSerializer
|
|
|
|
from core.models import (
|
|
Attribute,
|
|
AttributeGroup,
|
|
AttributeValue,
|
|
Brand,
|
|
Category,
|
|
Feedback,
|
|
Order,
|
|
OrderProduct,
|
|
Product,
|
|
ProductImage,
|
|
ProductTag,
|
|
PromoCode,
|
|
Promotion,
|
|
Stock,
|
|
Vendor,
|
|
Wishlist,
|
|
)
|
|
|
|
|
|
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()
|
|
image = SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Category
|
|
fields = [
|
|
"uuid",
|
|
"name",
|
|
"image",
|
|
"children",
|
|
]
|
|
|
|
def get_image(self, obj: Category) -> Optional[str]:
|
|
with suppress(ValueError):
|
|
return obj.image.url
|
|
return None
|
|
|
|
def get_children(self, obj) -> list[dict]:
|
|
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():
|
|
return (
|
|
CategorySimpleSerializer(children, many=True, context=self.context).data
|
|
if obj.children.exists()
|
|
else []
|
|
)
|
|
else:
|
|
return []
|
|
|
|
|
|
class BrandSimpleSerializer(ModelSerializer):
|
|
small_logo = SerializerMethodField()
|
|
big_logo = SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Brand
|
|
fields = [
|
|
"uuid",
|
|
"name",
|
|
"small_logo",
|
|
"big_logo",
|
|
]
|
|
|
|
def get_small_logo(self, obj: Brand) -> Optional[str]:
|
|
with suppress(ValueError):
|
|
return obj.small_logo.url
|
|
return None
|
|
|
|
def get_big_logo(self, obj: Brand) -> Optional[str]:
|
|
with suppress(ValueError):
|
|
return obj.big_logo.url
|
|
return None
|
|
|
|
|
|
class ProductTagSimpleSerializer(ModelSerializer):
|
|
class Meta:
|
|
model = ProductTag
|
|
fields = [
|
|
"uuid",
|
|
"tag_name",
|
|
"name",
|
|
]
|
|
|
|
|
|
class ProductImageSimpleSerializer(ModelSerializer):
|
|
product = 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(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)
|
|
|
|
rating = SerializerMethodField()
|
|
price = SerializerMethodField()
|
|
quantity = SerializerMethodField()
|
|
feedbacks_count = SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Product
|
|
fields = [
|
|
"uuid",
|
|
"name",
|
|
"is_digital",
|
|
"slug",
|
|
"description",
|
|
"partnumber",
|
|
"brand",
|
|
"feedbacks_count",
|
|
"category",
|
|
"tags",
|
|
"images",
|
|
"attributes",
|
|
"rating",
|
|
"price",
|
|
"quantity",
|
|
]
|
|
|
|
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
|
|
|
|
|
|
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(read_only=True)
|
|
products = ProductSimpleSerializer(many=True, read_only=True)
|
|
|
|
class Meta:
|
|
model = Wishlist
|
|
fields = [
|
|
"uuid",
|
|
"user",
|
|
"products",
|
|
]
|
|
|
|
|
|
class FeedbackSimpleSerializer(ModelSerializer):
|
|
order_product = 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(read_only=True)
|
|
promo_code = PromoCodeSimpleSerializer(read_only=True)
|
|
order_products = OrderProductSimpleSerializer(many=True, read_only=True)
|
|
|
|
class Meta:
|
|
model = Order
|
|
fields = [
|
|
"uuid",
|
|
"status",
|
|
"user",
|
|
"promo_code",
|
|
"order_products",
|
|
"buy_time",
|
|
]
|