Add shopping cart and product review features
Introduces Cart and CartItem models, admin, serializers, and API endpoints for shopping cart management for both authenticated and anonymous users. Adds Review model, serializers, and endpoints for product reviews, including public creation and retrieval. Updates ProductImage ordering, enhances order save logic with notification, and improves product and order endpoints with new actions and filters. Includes related migrations for commerce, configuration, social chat, and Deutsche Post integration.
This commit is contained in:
@@ -85,6 +85,8 @@ from .models import (
|
||||
OrderItem,
|
||||
Carrier,
|
||||
Payment,
|
||||
Cart,
|
||||
CartItem,
|
||||
)
|
||||
|
||||
from thirdparty.stripe.models import StripeModel
|
||||
@@ -466,8 +468,59 @@ class OrderReadSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
|
||||
class ReviewSerializerPublic(serializers.Serializer):
|
||||
class ReviewSerializerPublic(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Review
|
||||
fields = "__all__"
|
||||
fields = "__all__"
|
||||
read_only_fields = ['user', 'created_at', 'updated_at']
|
||||
|
||||
|
||||
# ----------------- CART SERIALIZERS -----------------
|
||||
|
||||
class CartItemSerializer(serializers.ModelSerializer):
|
||||
product_name = serializers.CharField(source='product.name', read_only=True)
|
||||
product_price = serializers.DecimalField(source='product.price', max_digits=10, decimal_places=2, read_only=True)
|
||||
subtotal = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = CartItem
|
||||
fields = ['id', 'product', 'product_name', 'product_price', 'quantity', 'subtotal', 'added_at']
|
||||
read_only_fields = ['id', 'added_at']
|
||||
|
||||
def get_subtotal(self, obj):
|
||||
return obj.get_subtotal()
|
||||
|
||||
def validate_quantity(self, value):
|
||||
if value < 1:
|
||||
raise serializers.ValidationError("Quantity must be at least 1")
|
||||
return value
|
||||
|
||||
|
||||
class CartItemCreateSerializer(serializers.Serializer):
|
||||
product_id = serializers.IntegerField()
|
||||
quantity = serializers.IntegerField(min_value=1, default=1)
|
||||
|
||||
def validate_product_id(self, value):
|
||||
try:
|
||||
Product.objects.get(pk=value, is_active=True)
|
||||
except Product.DoesNotExist:
|
||||
raise serializers.ValidationError("Product not found or inactive.")
|
||||
return value
|
||||
|
||||
|
||||
class CartSerializer(serializers.ModelSerializer):
|
||||
items = CartItemSerializer(many=True, read_only=True)
|
||||
total = serializers.SerializerMethodField()
|
||||
items_count = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Cart
|
||||
fields = ['id', 'user', 'items', 'total', 'items_count', 'created_at', 'updated_at']
|
||||
read_only_fields = ['id', 'user', 'created_at', 'updated_at']
|
||||
|
||||
def get_total(self, obj):
|
||||
return obj.get_total()
|
||||
|
||||
def get_items_count(self, obj):
|
||||
return obj.get_items_count()
|
||||
Reference in New Issue
Block a user