import logging from urllib.parse import urlparse from drf_spectacular.utils import extend_schema_field from rest_framework import exceptions, status from rest_framework import serializers from rest_framework.response import Response from apps.geology.models import Geology, Photo class GeologySerializer(serializers.ModelSerializer): class Meta: model = Geology fields = ( "id", "name", "title", "body1", "body2", "body3", "banner_title", "banner", "address", "image", "location", "composition", "isp", "analysis", "category", "created_at", "updated_at", ) def create(self, validated_data): try: request = self.context.get("request") photo_data1 = [] photo_data2 = [] for key in request.data: if key.startswith("description1[") and key.endswith("]"): index = key[len("description1[") : -1] file_key = f"image1[{index}]" photo_desc = request.data.get(key) photo_file = request.FILES.get(file_key) if not photo_file: return Response( { "error": f"File is required for photo item {index} in photos1" }, status=status.HTTP_400_BAD_REQUEST, ) if not photo_desc: photo_desc = photo_file.name photo_data1.append({"image": photo_file, "description": photo_desc}) if key.startswith("description2[") and key.endswith("]"): index = key[len("description2[") : -1] file_key = f"image2[{index}]" photo_desc = request.data.get(key) photo_file = request.FILES.get(file_key) if not photo_file: return Response( { "error": f"File is required for photo item {index} in photos2" }, status=status.HTTP_400_BAD_REQUEST, ) if not photo_desc: photo_desc = photo_file.name photo_data2.append({"image": photo_file, "description": photo_desc}) geology = Geology.objects.create( name=validated_data.get("name"), title=validated_data.get("title"), body1=validated_data.get("body1"), body2=validated_data.get("body2"), body3=validated_data.get("body3"), banner_title=validated_data.get("banner_title"), banner=validated_data.get("banner"), address=validated_data.get("address"), location=validated_data.get("location"), composition=validated_data.get("composition"), isp=validated_data.get("isp"), analysis=validated_data.get("analysis"), category=validated_data.get("category"), ) for photo in photo_data1: photo_instance = Photo.objects.create( image=photo["image"], description=photo["description"] ) geology.photos1.add(photo_instance) for photo in photo_data2: photo_instance = Photo.objects.create( image=photo["image"], description=photo["description"] ) geology.photos2.add(photo_instance) return geology except Exception as e: logging.error(f"Error in create method: {str(e)}") raise exceptions.ValidationError({"detail": str(e)}) class GeologyDetailSerializer(serializers.ModelSerializer): category = serializers.SerializerMethodField() photos1 = serializers.SerializerMethodField() photos2 = serializers.SerializerMethodField() class Meta: model = Geology fields = ( "id", "category", "banner_title", "banner", "name", "title", "body1", "address", "image", "location", "composition", "isp", "analysis", "body2", "photos1", "body3", "photos2", "created_at", "updated_at", ) def to_representation(self, instance): representation = super().to_representation(instance) if representation.get("banner"): parsed_url = urlparse(representation["banner"]) representation["banner"] = parsed_url.path return representation @extend_schema_field(serializers.DictField()) def get_category(self, obj): from apps.geology.serializers.category import CategorySerializer return CategorySerializer(obj.category).data @extend_schema_field(serializers.ListField(child=serializers.DictField())) def get_photos1(self, obj): from apps.geology.serializers.photo import PhotoSerializer return PhotoSerializer(obj.photos1.all(), many=True).data @extend_schema_field(serializers.ListField(child=serializers.DictField())) def get_photos2(self, obj): from apps.geology.serializers.photo import PhotoSerializer return PhotoSerializer(obj.photos2.all(), many=True).data