from rest_framework import serializers from django.core.files.uploadedfile import SimpleUploadedFile from utils.image_compression import maybe_compress_uploaded_file from ..models import ( Hadis, HadisCategory, HadisStatus, HadisTag, HadisCorrection, HadisInterpretation, HadisCollection, HadisSect, BookReference, BookReferenceImage, BookReferenceDocument, BookAuthor, BookAttribute, BookSubjectArea, BookType, Transmitters, TransmitterReliability, NarratorLayer, OpinionStatus ) from .category import LocalizedField class AdminHadisCategorySerializer(serializers.ModelSerializer): sect_type = serializers.CharField(source='sect.sect_type', read_only=True) title = LocalizedField() description = LocalizedField() class Meta: model = HadisCategory fields = [ "id", "title", "slug", "source_type", "order", "sect", "sect_type", "description", ] class AdminHadisStatusSerializer(serializers.ModelSerializer): title = serializers.JSONField() description = serializers.JSONField() class Meta: model = HadisStatus fields = ["id", "title", "slug", "color", "order", "description"] class AdminHadisTagSerializer(serializers.ModelSerializer): title = serializers.JSONField() class Meta: model = HadisTag fields = ["id", "title", "status"] class AdminHadisListSerializer(serializers.ModelSerializer): category_detail = AdminHadisCategorySerializer(source="category", read_only=True) hadis_status_detail = AdminHadisStatusSerializer(source="hadis_status", read_only=True) title = LocalizedField() title_narrator = LocalizedField() translation = LocalizedField() class Meta: model = Hadis fields = [ "id", "number", "slug", "title", "title_narrator", "text", "translation", "status", "category", "category_detail", "hadis_status", "hadis_status_detail", "created_at", "updated_at", ] read_only_fields = ["id", "slug", "created_at", "updated_at"] class AdminHadisDetailSerializer(serializers.ModelSerializer): category_detail = AdminHadisCategorySerializer(source="category", read_only=True) hadis_status_detail = AdminHadisStatusSerializer(source="hadis_status", read_only=True) tags_detail = AdminHadisTagSerializer(source="tags", many=True, read_only=True) category = serializers.PrimaryKeyRelatedField( queryset=HadisCategory.objects.all(), required=False, allow_null=True, ) hadis_status = serializers.PrimaryKeyRelatedField( queryset=HadisStatus.objects.all(), required=False, allow_null=True, ) tags = serializers.PrimaryKeyRelatedField( queryset=HadisTag.objects.all(), many=True, required=False, ) class Meta: model = Hadis fields = [ "id", "number", "slug", "category", "category_detail", "title_narrator", "title", "description", "text", "translation", "status", "hadis_status", "hadis_status_detail", "hadis_status_text", "address", "links", "tags", "tags_detail", "share_link", "explanation", "created_at", "updated_at", "embedded_in", ] read_only_fields = ["id", "slug", "share_link", "created_at", "updated_at"] def create(self, validated_data): tags = validated_data.pop("tags", []) hadis = super().create(validated_data) if tags: hadis.tags.set(tags) return hadis def update(self, instance, validated_data): tags = validated_data.pop("tags", None) hadis = super().update(instance, validated_data) if tags is not None: hadis.tags.set(tags) return hadis class AdminHadisCorrectionSerializer(serializers.ModelSerializer): hadis_detail = AdminHadisListSerializer(source="hadis", read_only=True) class Meta: model = HadisCorrection fields = [ "id", "hadis", "hadis_detail", "title", "slug", "text", "translation", "priority", "created_at", "updated_at", ] read_only_fields = ["id", "slug", "created_at", "updated_at"] class AdminHadisInterpretationSerializer(serializers.ModelSerializer): category_detail = AdminHadisCategorySerializer(source="category", read_only=True) class Meta: model = HadisInterpretation fields = [ "id", "category", "category_detail", "title", "text", "translation", "priority", "created_at", "updated_at", ] read_only_fields = ["id", "created_at", "updated_at"] class AbsoluteImageField(serializers.ImageField): def to_representation(self, value): if not value: return None request = self.context.get("request") url = value.url if hasattr(value, "url") else str(value) if request: return request.build_absolute_uri(url) return url class AbsoluteFileField(serializers.FileField): def to_representation(self, value): if not value: return None request = self.context.get("request") url = value.url if hasattr(value, "url") else str(value) if request: return request.build_absolute_uri(url) return url class AdminHadisSectArchiveSerializer(serializers.ModelSerializer): title = serializers.JSONField() description = serializers.JSONField() class Meta: model = HadisSect fields = ["id", "sect_type", "title", "description", "is_active", "order"] class AdminHadisCategoryArchiveParentSerializer(serializers.ModelSerializer): title = serializers.JSONField() class Meta: model = HadisCategory fields = ["id", "title", "slug"] class AdminHadisCategoryArchiveSerializer(serializers.ModelSerializer): parent_detail = AdminHadisCategoryArchiveParentSerializer(source="parent", read_only=True) sect_detail = AdminHadisSectArchiveSerializer(source="sect", read_only=True) title = serializers.JSONField() description = serializers.JSONField() xmind_file = AbsoluteFileField(required=False, allow_null=True) remove_xmind_file = serializers.BooleanField(write_only=True, required=False, default=False) parent = serializers.PrimaryKeyRelatedField( queryset=HadisCategory.objects.all(), required=False, allow_null=True, ) sect = serializers.PrimaryKeyRelatedField( queryset=HadisSect.objects.all(), required=True, ) class Meta: model = HadisCategory fields = [ "id", "parent", "parent_detail", "sect", "sect_detail", "source_type", "title", "description", "order", "xmind_file", "remove_xmind_file", "slug", "share_link", "xmind_share_link", ] read_only_fields = ["id", "share_link", "xmind_share_link"] def create(self, validated_data): validated_data.pop("remove_xmind_file", False) return super().create(validated_data) def update(self, instance, validated_data): remove_xmind_file = validated_data.pop("remove_xmind_file", False) if remove_xmind_file and instance.xmind_file: instance.xmind_file.delete(save=False) instance.xmind_file = None return super().update(instance, validated_data) class AdminHadisCollectionSerializer(serializers.ModelSerializer): title = serializers.JSONField() summary = serializers.JSONField() thumbnail = AbsoluteImageField(required=False, allow_null=True) remove_thumbnail = serializers.BooleanField(write_only=True, required=False, default=False) class Meta: model = HadisCollection fields = [ "id", "title", "slug", "summary", "status", "pin_top", "order", "thumbnail", "remove_thumbnail", "created_at", "updated_at", ] read_only_fields = ["id", "created_at", "updated_at"] def to_internal_value(self, data): mutable_data = data.copy() if hasattr(data, "copy") else data thumbnail = mutable_data.get("thumbnail") if hasattr(mutable_data, "get") else None if thumbnail and hasattr(thumbnail, "read"): compressed_bytes = maybe_compress_uploaded_file(thumbnail) if compressed_bytes is not None: mutable_data = mutable_data.copy() if hasattr(mutable_data, "copy") else mutable_data mutable_data["thumbnail"] = SimpleUploadedFile( name=getattr(thumbnail, "name", "image"), content=compressed_bytes, content_type=getattr(thumbnail, "content_type", None), ) return super().to_internal_value(mutable_data) def create(self, validated_data): validated_data.pop("remove_thumbnail", False) return super().create(validated_data) def update(self, instance, validated_data): remove_thumbnail = validated_data.pop("remove_thumbnail", False) if remove_thumbnail and instance.thumbnail: instance.thumbnail.delete(save=False) instance.thumbnail = None return super().update(instance, validated_data) class AdminTransmitterReliabilitySerializer(serializers.ModelSerializer): class Meta: model = TransmitterReliability fields = ["id", "title", "slug", "color", "main_color_code"] class AdminNarratorLayerSerializer(serializers.ModelSerializer): name = serializers.JSONField() description = serializers.JSONField() class Meta: model = NarratorLayer fields = ["id", "name", "number", "description", "slug", "created_at", "updated_at"] read_only_fields = ["id", "created_at", "updated_at"] class AdminOpinionStatusSerializer(serializers.ModelSerializer): title = serializers.JSONField() class Meta: model = OpinionStatus fields = ["id", "title", "slug", "color", "main_color_code"] class AdminTransmitterListSerializer(serializers.ModelSerializer): reliability_detail = AdminTransmitterReliabilitySerializer(source="reliability", read_only=True) full_name = serializers.JSONField() known_as = serializers.JSONField() nickname = serializers.JSONField() thumbnail = AbsoluteImageField(required=False, allow_null=True) share_link = serializers.CharField(read_only=True) class Meta: model = Transmitters fields = [ "id", "full_name", "slug", "birth_year_hijri", "death_year_hijri", "known_as", "nickname", "reliability", "reliability_detail", "madhhab", "generation", "thumbnail", "share_link", "created_at", "updated_at", ] read_only_fields = ["id", "slug", "share_link", "created_at", "updated_at"] class AdminTransmitterDetailSerializer(serializers.ModelSerializer): reliability_detail = AdminTransmitterReliabilitySerializer(source="reliability", read_only=True) full_name = serializers.JSONField() kunya = serializers.JSONField() known_as = serializers.JSONField() nickname = serializers.JSONField() origin = serializers.JSONField() lived_in = serializers.JSONField() died_in = serializers.JSONField() description = serializers.JSONField() thumbnail = AbsoluteImageField(required=False, allow_null=True) reliability = serializers.PrimaryKeyRelatedField( queryset=TransmitterReliability.objects.all(), required=False, ) share_link = serializers.CharField(read_only=True) class Meta: model = Transmitters fields = [ "id", "full_name", "kunya", "known_as", "nickname", "slug", "legacy_number", "legacy_id", "birth_year_hijri", "death_year_hijri", "age_at_death", "generation", "reliability", "reliability_detail", "madhhab", "in_sahih_muslim", "in_sahih_bukhari", "origin", "lived_in", "died_in", "description", "thumbnail", "share_link", "created_at", "updated_at", ] read_only_fields = ["id", "slug", "share_link", "created_at", "updated_at", "reliability_detail"] class AdminBookSubjectAreaSerializer(serializers.ModelSerializer): class Meta: model = BookSubjectArea fields = ["id", "title", "created_at", "updated_at"] read_only_fields = ["id", "created_at", "updated_at"] class AdminBookTypeSerializer(serializers.ModelSerializer): class Meta: model = BookType fields = ["id", "title", "created_at", "updated_at"] read_only_fields = ["id", "created_at", "updated_at"] class AdminBookAuthorSerializer(serializers.ModelSerializer): class Meta: model = BookAuthor fields = ["id", "name", "birth_year_hijri", "death_year_hijri", "birth_year_miladi", "death_year_miladi"] class AdminBookAttributeSerializer(serializers.ModelSerializer): class Meta: model = BookAttribute fields = ["id", "book_reference", "title", "value"] class AdminBookReferenceImageSerializer(serializers.ModelSerializer): image = AbsoluteImageField(required=True) volume = serializers.SerializerMethodField() class Meta: model = BookReferenceImage fields = ["id", "book_reference", "image", "volume", "order", "description"] def get_volume(self, obj): return obj.book_volume.title if getattr(obj, 'book_volume', None) else "" class AdminBookReferenceDocumentSerializer(serializers.ModelSerializer): file = AbsoluteFileField(required=True) volume = serializers.SerializerMethodField() class Meta: model = BookReferenceDocument fields = ["id", "book_reference", "file", "volume", "title", "order"] def get_volume(self, obj): return obj.book_volume.title if getattr(obj, 'book_volume', None) else "" class AdminBookReferenceListSerializer(serializers.ModelSerializer): volume = serializers.SerializerMethodField() publisher = serializers.SerializerMethodField() year_of_publication = serializers.SerializerMethodField() class Meta: model = BookReference fields = [ "id", "title", "slug", "volume", "publisher", "year_of_publication", "rate", "created_at", ] def get_volume(self, obj): vol = obj.volumes.first() return vol.title if vol else "" def get_publisher(self, obj): edition = obj.editions.first() return edition.publisher if edition else [] def get_year_of_publication(self, obj): edition = obj.editions.first() return edition.year_of_publication if edition else "" class AdminBookReferenceDetailSerializer(serializers.ModelSerializer): subject_area_detail = AdminBookSubjectAreaSerializer(source="subject_area", many=True, read_only=True) type_detail = AdminBookTypeSerializer(source="type", read_only=True) authors_detail = AdminBookAuthorSerializer(source="authors", many=True, read_only=True) subject_area = serializers.PrimaryKeyRelatedField( queryset=BookSubjectArea.objects.all(), many=True, required=False, ) type = serializers.PrimaryKeyRelatedField( queryset=BookType.objects.all(), required=False, allow_null=True, ) authors = serializers.PrimaryKeyRelatedField( queryset=BookAuthor.objects.all(), many=True, required=False, ) source_url = serializers.SerializerMethodField() isbn = serializers.SerializerMethodField() volume = serializers.SerializerMethodField() number_of_volumes = serializers.SerializerMethodField() year_of_publication = serializers.SerializerMethodField() publisher = serializers.SerializerMethodField() city_of_publication = serializers.SerializerMethodField() country_of_publication = serializers.SerializerMethodField() edition_number = serializers.SerializerMethodField() def get_source_url(self, obj): ed = obj.editions.first() return ed.source_url if ed else "" def get_isbn(self, obj): ed = obj.editions.first() return ed.isbn if ed else "" def get_volume(self, obj): vol = obj.volumes.first() return vol.title if vol else "" def get_number_of_volumes(self, obj): ed = obj.editions.first() return ed.number_of_volumes if ed else None def get_year_of_publication(self, obj): ed = obj.editions.first() return ed.year_of_publication if ed else "" def get_publisher(self, obj): ed = obj.editions.first() return ed.publisher if ed else [] def get_city_of_publication(self, obj): ed = obj.editions.first() return ed.city_of_publication if ed else [] def get_country_of_publication(self, obj): ed = obj.editions.first() return ed.country_of_publication if ed else [] def get_edition_number(self, obj): ed = obj.editions.first() return ed.edition_number if ed else "" class Meta: model = BookReference fields = [ "id", "legacy_id", "source_url", "title", "description", "language", "isbn", "volume", "number_of_volumes", "year_of_publication", "number_page", "slug", "publisher", "subject_area", "subject_area_detail", "type", "type_detail", "order", "researcher", "city_of_publication", "country_of_publication", "edition_number", "rate", "authors", "authors_detail", "created_at", "updated_at", "share_link", ] read_only_fields = ["id", "slug", "created_at", "updated_at", "share_link"] def create(self, validated_data): subject_area = validated_data.pop("subject_area", []) authors = validated_data.pop("authors", []) book = super().create(validated_data) if subject_area: book.subject_area.set(subject_area) if authors: book.authors.set(authors) return book def update(self, instance, validated_data): subject_area = validated_data.pop("subject_area", None) authors = validated_data.pop("authors", None) book = super().update(instance, validated_data) if subject_area is not None: book.subject_area.set(subject_area) if authors is not None: book.authors.set(authors) return book