Files
vendora/Backend/app/serializers.py
T
2025-04-23 22:16:54 +05:45

178 lines
6.5 KiB
Python

from rest_framework import serializers
from .models import User, Category, Product, Rating, Order, OrderItem, CartItem, Cart, Favorite
class UserSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True)
class Meta:
model = User
fields = ['id', 'username', 'first_name', 'last_name', 'email', 'password',
'phone', 'address', 'created_at']
read_only_fields = ['id', 'created_at']
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', '')
)
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()
class Meta:
model = Product
fields = ['id', 'name', 'description', 'price', 'image', 'category', 'stock','color','size',
'category_name', 'average_rating', 'created_at']
read_only_fields = ['id', 'created_at', 'category_name', 'average_rating']
def get_average_rating(self, obj):
ratings = obj.ratings.all()
if ratings:
return sum(rating.rating for rating in ratings) / len(ratings)
return 0
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']