Fix schema generation to allow propre types in front (#2404)

This commit is contained in:
petitminion 2025-02-20 15:04:25 +00:00
parent c1b0b71479
commit 6c6cb60a28
5 changed files with 74 additions and 49 deletions

View File

@ -293,7 +293,17 @@ class AttachmentSerializer(serializers.Serializer):
file = StripExifImageField(write_only=True)
urls = serializers.SerializerMethodField()
@extend_schema_field(OpenApiTypes.OBJECT)
@extend_schema_field(
{
"type": "object",
"properties": {
"original": {"type": "string"},
"small_square_crop": {"type": "string"},
"medium_square_crop": {"type": "string"},
"large_square_crop": {"type": "string"},
},
}
)
def get_urls(self, o):
urls = {}
urls["source"] = o.url

View File

@ -140,10 +140,11 @@ class ArtistWithAlbumsSerializer(OptionalDescriptionMixin, serializers.Serialize
return getattr(o, "_tracks_count", 0)
class SimpleArtistSerializer(serializers.ModelSerializer):
class ArtistSerializer(serializers.ModelSerializer):
cover = CoverField(allow_null=True, required=False)
description = common_serializers.ContentSerializer(allow_null=True, required=False)
channel = serializers.UUIDField(allow_null=True, required=False)
tags = serializers.SerializerMethodField()
class Meta:
model = models.Artist
@ -160,59 +161,21 @@ class SimpleArtistSerializer(serializers.ModelSerializer):
"cover",
"channel",
"attributed_to",
"tags",
)
class ArtistCreditSerializer(serializers.ModelSerializer):
artist = SimpleArtistSerializer()
class Meta:
model = models.ArtistCredit
fields = ["artist", "credit", "joinphrase", "index"]
class AlbumSerializer(OptionalDescriptionMixin, serializers.Serializer):
artist_credit = ArtistCreditSerializer(many=True)
description = common_serializers.ContentSerializer(allow_null=True, required=False)
cover = CoverField(allow_null=True)
is_playable = serializers.SerializerMethodField()
tags = serializers.SerializerMethodField()
tracks_count = serializers.SerializerMethodField()
attributed_to = APIActorSerializer()
id = serializers.IntegerField()
fid = serializers.URLField()
mbid = serializers.UUIDField()
title = serializers.CharField()
release_date = serializers.DateField()
creation_date = serializers.DateTimeField()
is_local = serializers.BooleanField()
duration = serializers.SerializerMethodField(read_only=True)
def get_tracks_count(self, o) -> int:
return len(o.tracks.all())
def get_is_playable(self, obj) -> bool:
try:
return any(
[
bool(getattr(t, "is_playable_by_actor", None))
for t in obj.tracks.all()
]
)
except AttributeError:
return None
@extend_schema_field({"type": "array", "items": {"type": "string"}})
def get_tags(self, obj):
tagged_items = getattr(obj, "_prefetched_tagged_items", [])
return [ti.tag.name for ti in tagged_items]
def get_duration(self, obj) -> int:
try:
return obj.duration
except AttributeError:
# no annotation?
return 0
class ArtistCreditSerializer(serializers.ModelSerializer):
artist = ArtistSerializer()
class Meta:
model = models.ArtistCredit
fields = ["artist", "credit", "joinphrase", "index"]
class TrackAlbumSerializer(serializers.ModelSerializer):
@ -318,6 +281,51 @@ class TrackSerializer(OptionalDescriptionMixin, serializers.Serializer):
return bool(getattr(obj, "playable_uploads", []))
class AlbumSerializer(OptionalDescriptionMixin, serializers.Serializer):
artist_credit = ArtistCreditSerializer(many=True)
cover = CoverField(allow_null=True)
is_playable = serializers.SerializerMethodField()
tags = serializers.SerializerMethodField()
tracks_count = serializers.SerializerMethodField()
attributed_to = APIActorSerializer()
id = serializers.IntegerField()
fid = serializers.URLField()
mbid = serializers.UUIDField()
title = serializers.CharField()
release_date = serializers.DateField()
creation_date = serializers.DateTimeField()
is_local = serializers.BooleanField()
duration = serializers.SerializerMethodField(read_only=True)
tracks = TrackSerializer(many=True, allow_null=True)
description = common_serializers.ContentSerializer(allow_null=True, required=False)
def get_tracks_count(self, o) -> int:
return len(o.tracks.all())
def get_is_playable(self, obj) -> bool:
try:
return any(
[
bool(getattr(t, "is_playable_by_actor", None))
for t in obj.tracks.all()
]
)
except AttributeError:
return None
@extend_schema_field({"type": "array", "items": {"type": "string"}})
def get_tags(self, obj):
tagged_items = getattr(obj, "_prefetched_tagged_items", [])
return [ti.tag.name for ti in tagged_items]
def get_duration(self, obj) -> int:
try:
return obj.duration
except AttributeError:
# no annotation?
return 0
@common_serializers.track_fields_for_update("name", "description", "privacy_level")
class LibraryForOwnerSerializer(serializers.ModelSerializer):
uploads_count = serializers.SerializerMethodField()

View File

@ -256,5 +256,5 @@ class PlaylistViewSet(
except models.PlaylistTrack.DoesNotExist:
return Response(status=404)
artists = music_models.Artist.objects.filter(pk__in=artists_pks)
serializer = music_serializers.SimpleArtistSerializer(artists, many=True)
serializer = music_serializers.ArtistSerializer(artists, many=True)
return Response(serializer.data, status=200)

View File

@ -199,6 +199,9 @@ def test_album_serializer(factories, to_api_date):
"tags": [],
"attributed_to": federation_serializers.APIActorSerializer(actor).data,
"description": None,
"tracks": [
serializers.TrackSerializer(track).data for track in album.tracks.all()
],
}
serializer = serializers.AlbumSerializer(
album.__class__.objects.with_tracks_count().get(pk=album.pk)
@ -232,6 +235,9 @@ def test_track_album_serializer(factories, to_api_date):
"tags": [],
"attributed_to": federation_serializers.APIActorSerializer(actor).data,
"description": None,
"tracks": [
serializers.TrackSerializer(track).data for track in album.tracks.all()
],
}
serializer = serializers.AlbumSerializer(
album.__class__.objects.with_tracks_count().get(pk=album.pk)

View File

@ -0,0 +1 @@
Fix schema generation to allow propre types in front (#2404)