from rest_framework import serializers from django.db.models import Avg from core.apps.api.models import FeedbackModel, FeedbackImageModel, AdModel class FeedbackImageSerializer(serializers.ModelSerializer): class Meta: model = FeedbackImageModel fields = ["id", "image"] read_only_fields = ["id"] class FeedbackListSerializer(serializers.ModelSerializer): """List serializer for feedback with user and ad info""" user_name = serializers.CharField(source="user.username", read_only=True) ad_name = serializers.CharField(source="ad.name", read_only=True) images = FeedbackImageSerializer(many=True, read_only=True) class Meta: model = FeedbackModel fields = [ "id", "star", "user", "user_name", "ad", "ad_name", "comment", "images", "created_at" ] read_only_fields = ["id", "user", "user_name", "ad_name", "created_at"] class FeedbackDetailSerializer(FeedbackListSerializer): """Detailed feedback serializer""" class Meta(FeedbackListSerializer.Meta): fields = FeedbackListSerializer.Meta.fields + ["updated_at"] class FeedbackCreateSerializer(serializers.ModelSerializer): """Create feedback serializer""" images = serializers.ListField( child=serializers.ImageField(), write_only=True, required=False ) class Meta: model = FeedbackModel fields = ["ad", "star", "comment", "images"] def validate_star(self, value): """Validate star rating is between 1 and 5""" if not 1 <= value <= 5: raise serializers.ValidationError("Rating must be between 1 and 5") return value def create(self, validated_data): images_data = validated_data.pop("images", []) validated_data["user"] = self.context["request"].user feedback = FeedbackModel.objects.create(**validated_data) # Create feedback images for image_data in images_data: FeedbackImageModel.objects.create( feedback=feedback, image=image_data ) return feedback class FeedbackUpdateSerializer(serializers.ModelSerializer): """Update feedback serializer""" class Meta: model = FeedbackModel fields = ["star", "comment"] def validate_star(self, value): if not 1 <= value <= 5: raise serializers.ValidationError("Rating must be between 1 and 5") return value