327 lines
9.6 KiB
Python
327 lines
9.6 KiB
Python
from rest_framework import serializers
|
|
from .models import (
|
|
User,
|
|
Category,
|
|
Product,
|
|
Rating,
|
|
Order,
|
|
OrderItem,
|
|
CartItem,
|
|
Cart,
|
|
Favorite,
|
|
PrivacyPolicy,
|
|
FAQ,
|
|
Contact,
|
|
Slider,
|
|
Coupon,
|
|
Notification
|
|
)
|
|
|
|
|
|
class UserSerializer(serializers.ModelSerializer):
|
|
password = serializers.CharField(write_only=True)
|
|
|
|
class Meta:
|
|
model = User
|
|
fields = [
|
|
"id",
|
|
"username",
|
|
"first_name",
|
|
"last_name",
|
|
"gender",
|
|
"email",
|
|
"password",
|
|
"phone",
|
|
"address",
|
|
"profile_picture",
|
|
"created_at",
|
|
]
|
|
read_only_fields = ["id", "created_at"]
|
|
extra_kwargs = {
|
|
'gender': {'required': False},
|
|
'phone': {'required': False},
|
|
'address': {'required': False},
|
|
}
|
|
|
|
def create(self, validated_data):
|
|
# Use the create_user method instead of direct creation
|
|
user = User.objects.create_user(
|
|
username=validated_data["username"],
|
|
email=validated_data["email"],
|
|
password=validated_data["password"],
|
|
first_name=validated_data.get("first_name", ""),
|
|
last_name=validated_data.get("last_name", ""),
|
|
phone=validated_data.get("phone", ""),
|
|
address=validated_data.get("address", ""),
|
|
gender=validated_data.get("gender", ""),
|
|
)
|
|
return user
|
|
|
|
|
|
class CategorySerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Category
|
|
fields = ["id", "name", "image", "created_at"]
|
|
read_only_fields = ["id", "created_at"]
|
|
|
|
|
|
class RatingSerializer(serializers.ModelSerializer):
|
|
username = serializers.ReadOnlyField(source="user.username")
|
|
|
|
class Meta:
|
|
model = Rating
|
|
fields = [
|
|
"id",
|
|
"product",
|
|
"user",
|
|
"username",
|
|
"rating",
|
|
"comment",
|
|
"created_at",
|
|
]
|
|
read_only_fields = ["id", "created_at", "username"]
|
|
|
|
|
|
class ProductSerializer(serializers.ModelSerializer):
|
|
category_name = serializers.ReadOnlyField(source="category.name")
|
|
average_rating = serializers.SerializerMethodField()
|
|
image_url = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Product
|
|
fields = [
|
|
"id",
|
|
"name",
|
|
"description",
|
|
"price",
|
|
"image",
|
|
"image_url",
|
|
"category",
|
|
"stock",
|
|
"color",
|
|
"size",
|
|
"category_name",
|
|
"average_rating",
|
|
"created_at",
|
|
]
|
|
read_only_fields = ["id", "created_at", "category_name", "average_rating", "image_url"]
|
|
|
|
def get_average_rating(self, obj):
|
|
try:
|
|
return float(obj.average_rating) if obj.average_rating is not None else 0.0
|
|
except (TypeError, AttributeError):
|
|
return 0.0
|
|
|
|
def get_image_url(self, obj):
|
|
if obj.image:
|
|
request = self.context.get('request')
|
|
if request is not None:
|
|
return request.build_absolute_uri(obj.image.url)
|
|
return obj.image.url
|
|
return None
|
|
|
|
|
|
class ProductDetailSerializer(ProductSerializer):
|
|
ratings = RatingSerializer(many=True, read_only=True)
|
|
|
|
class Meta(ProductSerializer.Meta):
|
|
fields = ProductSerializer.Meta.fields + ["ratings"]
|
|
|
|
|
|
class OrderItemSerializer(serializers.ModelSerializer):
|
|
product_name = serializers.ReadOnlyField(source="product.name")
|
|
product_image = serializers.ImageField(source="product.image", read_only=True)
|
|
subtotal = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = OrderItem
|
|
fields = [
|
|
"id",
|
|
"product",
|
|
"product_name",
|
|
"product_image",
|
|
"quantity",
|
|
"price",
|
|
"subtotal",
|
|
]
|
|
read_only_fields = ["id", "product_name", "product_image", "subtotal"]
|
|
|
|
def get_subtotal(self, obj):
|
|
return obj.get_subtotal()
|
|
|
|
|
|
class OrderItemCreateSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = OrderItem
|
|
fields = ["product", "quantity"]
|
|
|
|
|
|
class OrderSerializer(serializers.ModelSerializer):
|
|
user_name = serializers.ReadOnlyField(source="user.get_full_name")
|
|
order_items = OrderItemSerializer(many=True, read_only=True)
|
|
items = OrderItemCreateSerializer(many=True, write_only=True, required=False)
|
|
|
|
class Meta:
|
|
model = Order
|
|
fields = [
|
|
"id",
|
|
"user",
|
|
"user_name",
|
|
"total_price",
|
|
"status",
|
|
"shipping_address",
|
|
"created_at",
|
|
"order_items",
|
|
"items",
|
|
]
|
|
read_only_fields = [
|
|
"id",
|
|
"created_at",
|
|
"user_name",
|
|
"total_price",
|
|
"order_items",
|
|
]
|
|
|
|
def create(self, validated_data):
|
|
items_data = validated_data.pop("items", [])
|
|
order = Order.objects.create(**validated_data)
|
|
|
|
# Create order items if provided
|
|
for item_data in items_data:
|
|
product = item_data.get("product")
|
|
quantity = item_data.get("quantity", 1)
|
|
order.add_product(product, quantity)
|
|
|
|
return order
|
|
|
|
def update(self, instance, validated_data):
|
|
items_data = validated_data.pop("items", [])
|
|
|
|
# Update the order fields
|
|
for attr, value in validated_data.items():
|
|
setattr(instance, attr, value)
|
|
instance.save()
|
|
|
|
# Add new items if provided
|
|
for item_data in items_data:
|
|
product = item_data.get("product")
|
|
quantity = item_data.get("quantity", 1)
|
|
instance.add_product(product, quantity)
|
|
|
|
return instance
|
|
|
|
|
|
class CartItemSerializer(serializers.ModelSerializer):
|
|
product_name = serializers.CharField(source="product.name", read_only=True)
|
|
product_price = serializers.SerializerMethodField()
|
|
product_image = serializers.SerializerMethodField()
|
|
subtotal = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = CartItem
|
|
fields = [
|
|
"id",
|
|
"product",
|
|
"product_name",
|
|
"product_price",
|
|
"product_image",
|
|
"quantity",
|
|
"subtotal",
|
|
"created_at",
|
|
"updated_at",
|
|
]
|
|
read_only_fields = ["created_at", "updated_at"]
|
|
|
|
def get_subtotal(self, obj):
|
|
try:
|
|
return float(obj.product.price * obj.quantity)
|
|
except (AttributeError, TypeError):
|
|
return 0.0
|
|
|
|
def get_product_price(self, obj):
|
|
try:
|
|
return float(obj.product.price)
|
|
except (AttributeError, TypeError):
|
|
return 0.0
|
|
|
|
def get_product_image(self, obj):
|
|
if obj.product and obj.product.image:
|
|
request = self.context.get("request")
|
|
if request is not None:
|
|
return request.build_absolute_uri(obj.product.image.url)
|
|
return obj.product.image.url
|
|
return None
|
|
|
|
|
|
class CartSerializer(serializers.ModelSerializer):
|
|
items = CartItemSerializer(many=True, read_only=True)
|
|
total = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Cart
|
|
fields = ["id", "user", "items", "total", "created_at", "updated_at"]
|
|
read_only_fields = ["created_at", "updated_at"]
|
|
|
|
def get_total(self, obj):
|
|
return obj.get_total()
|
|
|
|
|
|
class FavoriteSerializer(serializers.ModelSerializer):
|
|
product = ProductSerializer(read_only=True)
|
|
|
|
class Meta:
|
|
model = Favorite
|
|
fields = ["id", "product", "created_at"]
|
|
read_only_fields = ["id", "created_at"]
|
|
|
|
|
|
class PrivacyPolicySerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = PrivacyPolicy
|
|
fields = ['id', 'title', 'content', 'last_updated']
|
|
|
|
|
|
class FAQSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = FAQ
|
|
fields = ['id', 'question', 'answer', 'category', 'is_active', 'created_at', 'updated_at']
|
|
read_only_fields = ['id', 'created_at', 'updated_at']
|
|
|
|
|
|
class ContactSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Contact
|
|
fields = ['id', 'contact_type', 'title', 'value', 'is_active', 'created_at', 'updated_at']
|
|
read_only_fields = ['created_at', 'updated_at']
|
|
|
|
|
|
class SliderSerializer(serializers.ModelSerializer):
|
|
image_url = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Slider
|
|
fields = ('id', 'title', 'description', 'image', 'image_url', 'category', 'is_active', 'created_at', 'updated_at')
|
|
read_only_fields = ('created_at', 'updated_at')
|
|
|
|
def get_image_url(self, obj):
|
|
if obj.image:
|
|
return self.context['request'].build_absolute_uri(obj.image_url)
|
|
return None
|
|
|
|
|
|
class CouponSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Coupon
|
|
fields = ['id', 'code', 'discount_type', 'discount_value', 'min_purchase',
|
|
'max_discount', 'is_active', 'start_date', 'end_date']
|
|
read_only_fields = ['id', 'created_at', 'updated_at']
|
|
|
|
|
|
class NotificationSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Notification
|
|
fields = ['id', 'type', 'message', 'read', 'created_at', 'order', 'coupon']
|
|
read_only_fields = ['created_at']
|
|
|
|
|