From 57588e4bce67e3aa1f4147cbbdf366820cdd1c80 Mon Sep 17 00:00:00 2001 From: Ernesto Rico Schmidt <ernesto@helsinki.at> Date: Thu, 22 Feb 2024 00:26:27 -0400 Subject: [PATCH] fix: fix & clean-up serializers Closes: 178, 201 --- program/serializers.py | 260 ++++++++++++++++++++++++++--------------- 1 file changed, 163 insertions(+), 97 deletions(-) diff --git a/program/serializers.py b/program/serializers.py index c2ddc568..f84cccd9 100644 --- a/program/serializers.py +++ b/program/serializers.py @@ -50,7 +50,7 @@ from program.models import ( Type, UserProfile, ) -from program.utils import delete_links, get_audio_url +from program.utils import delete_links SOLUTION_CHOICES = { "theirs": "Discard projected timeslot. Keep existing timeslot(s).", @@ -165,12 +165,23 @@ class UserSerializer(serializers.ModelSerializer): Update and return an existing User instance, given the validated data. """ - instance.first_name = validated_data.get("first_name", instance.first_name) - instance.last_name = validated_data.get("last_name", instance.last_name) - instance.email = validated_data.get("email", instance.email) - instance.is_active = validated_data.get("is_active", instance.is_active) - instance.is_staff = validated_data.get("is_staff", instance.is_staff) - instance.is_superuser = validated_data.get("is_superuser", instance.is_superuser) + if "first_name" in validated_data: + instance.first_name = validated_data.get("first_name") + + if "last_name" in validated_data: + instance.last_name = validated_data.get("last_name") + + if "email" in validated_data: + instance.email = validated_data.get("email") + + if "is_active" in validated_data: + instance.is_active = validated_data.get("is_active") + + if "is_staff" in validated_data: + instance.is_staff = validated_data.get("is_staff") + + if "is_superuser" in validated_data: + instance.is_superuser = validated_data.get("is_superuser") profile_data = validated_data.pop("profile") if "profile" in validated_data else None @@ -181,8 +192,12 @@ class UserSerializer(serializers.ModelSerializer): except ObjectDoesNotExist: profile = UserProfile.objects.create(user=instance, **profile_data) - profile.cba_username = profile_data.get("cba_username") - profile.cba_user_token = profile_data.get("cba_user_token") + if "cba_username" in profile_data: + profile.cba_username = profile_data.get("cba_username") + + if "cba_user_token" in profile_data: + profile.cba_user_token = profile_data.get("cba_user_token") + profile.updated_by = self.context.get("request").user.username profile.save() @@ -299,11 +314,17 @@ class ImageSerializer(serializers.ModelSerializer): def update(self, instance, validated_data): """Update and return an existing Image instance, given the validated data.""" - # Only these fields can be updated. - instance.alt_text = validated_data.get("alt_text", instance.alt_text) - instance.credits = validated_data.get("credits", instance.credits) - instance.image.ppoi = validated_data.get("ppoi", instance.ppoi) - instance.license = validated_data.get("license", instance.license) + if "alt_text" in validated_data: + instance.alt_text = validated_data.get("alt_text") + + if "credits" in validated_data: + instance.credits = validated_data.get("credits") + + if "license" in validated_data: + instance.license = validated_data.get("license") + + if "ppoi" in validated_data: + instance.image.ppoi = validated_data.get("ppoi") instance.save() @@ -343,10 +364,12 @@ class HostSerializer(serializers.ModelSerializer): Create and return a new Host instance, given the validated data. """ - # optional inline + # optional nested objects links_data = validated_data.pop("links", []) + # optional many-to-many owners = validated_data.pop("owners", []) + # optional foreign key validated_data["image"] = validated_data.pop("image_id", None) @@ -396,14 +419,22 @@ class HostSerializer(serializers.ModelSerializer): detail="You are not allowed to edit the host’s name." ) - instance.biography = validated_data.get("biography", instance.biography) - instance.name = validated_data.get("name", instance.name) + if "biography" in validated_data: + instance.biography = validated_data.get("biography") + + if "name" in validated_data: + instance.name = validated_data.get("name") # Only update these fields if the user superuser, ignore otherwise if user.is_superuser: - instance.email = validated_data.get("email", instance.email) - instance.image = validated_data.get("image_id", instance.image) - instance.is_active = validated_data.get("is_active", instance.is_active) + if "email" in validated_data: + instance.email = validated_data.get("email") + + if "image" in validated_data: + instance.image = validated_data.get("image") + + if "is_active" in validated_data: + instance.is_active = validated_data.get("is_active") # optional nested objects if links_data := validated_data.get("links"): @@ -413,8 +444,8 @@ class HostSerializer(serializers.ModelSerializer): HostLink.objects.create(host=instance, **link_data) # optional many-to-many - if owners := validated_data.get("owners"): - instance.owners.set(owners) + if "owners" in validated_data.get("owners"): + instance.owners.set(validated_data.get("owners", [])) instance.updated_by = self.context.get("request").user.username @@ -466,20 +497,20 @@ class ShowSerializer(serializers.HyperlinkedModelSerializer): many=True, queryset=Category.objects.all(), source="category" ) funding_category_id = serializers.PrimaryKeyRelatedField( - queryset=FundingCategory.objects.all() + queryset=FundingCategory.objects.all(), source="funding_category" ) host_ids = serializers.PrimaryKeyRelatedField( many=True, queryset=Host.objects.all(), source="hosts" ) image_id = serializers.PrimaryKeyRelatedField( - allow_null=True, queryset=Image.objects.all(), required=False + allow_null=True, queryset=Image.objects.all(), required=False, source="image" ) language_ids = serializers.PrimaryKeyRelatedField( many=True, queryset=Language.objects.all(), source="language" ) links = HostLinkSerializer(many=True, required=False) logo_id = serializers.PrimaryKeyRelatedField( - allow_null=True, queryset=Image.objects.all(), required=False + allow_null=True, queryset=Image.objects.all(), required=False, source="logo" ) music_focus_ids = serializers.PrimaryKeyRelatedField( many=True, queryset=MusicFocus.objects.all(), source="music_focus" @@ -488,12 +519,12 @@ class ShowSerializer(serializers.HyperlinkedModelSerializer): many=True, queryset=User.objects.all(), source="owners" ) predecessor_id = serializers.PrimaryKeyRelatedField( - allow_null=True, queryset=Show.objects.all(), required=False + allow_null=True, queryset=Show.objects.all(), required=False, source="predecessor" ) topic_ids = serializers.PrimaryKeyRelatedField( many=True, queryset=Topic.objects.all(), source="topic" ) - type_id = serializers.PrimaryKeyRelatedField(queryset=Type.objects.all()) + type_id = serializers.PrimaryKeyRelatedField(queryset=Type.objects.all(), source="type") class Meta: model = Show @@ -542,7 +573,7 @@ class ShowSerializer(serializers.HyperlinkedModelSerializer): owners = validated_data.pop("owners") topic = validated_data.pop("topic") - # optional many-to-many + # optional nested objects links_data = validated_data.pop("links", []) # required foreign key @@ -596,7 +627,7 @@ class ShowSerializer(serializers.HyperlinkedModelSerializer): ] # Only superusers and owners of a show with edit permissions are allowed to update it - # Being a privileged user overrides the ownership + # Being a superuser overrides the ownership if not (user.is_superuser or (user_is_owner and len(user_edit_permissions) > 0)): raise exceptions.PermissionDenied(detail="You are not allowed to update this show.") @@ -619,49 +650,71 @@ class ShowSerializer(serializers.HyperlinkedModelSerializer): detail="You are not allowed to edit the show’s short description." ) - instance.description = validated_data.get("description", instance.description) - instance.name = validated_data.get("name", instance.name) - instance.short_description = validated_data.get( - "short_description", instance.short_description - ) + if "description" in validated_data: + instance.description = validated_data.get("description") + + if "name" in validated_data: + instance.name = validated_data.get("name") + + if "short_description" in validated_data: + instance.short_description = validated_data.get("short_description") # Only update these fields if the user is superuser, ignore otherwise if user.is_superuser: - instance.cba_series_id = validated_data.get("cba_series_id", instance.cba_series_id) - instance.default_playlist_id = validated_data.get( - "default_playlist_id", instance.default_playlist_id - ) - instance.email = validated_data.get("email", instance.email) - instance.funding_category = validated_data.get( - "funding_category_id", instance.funding_category - ) - instance.image = validated_data.get("image_id", instance.image) - instance.internal_note = validated_data.get("internal_note", instance.internal_note) - instance.is_active = validated_data.get("is_active", instance.is_active) - instance.is_public = validated_data.get("is_public", instance.is_public) - instance.logo = validated_data.get("logo_id", instance.logo) - instance.predecessor = validated_data.get("predecessor_id", instance.predecessor) - instance.slug = validated_data.get("slug", instance.slug) - instance.type = validated_data.get("type", instance.type) + if "cba_series_id" in validated_data: + instance.cba_series_id = validated_data.get("cba_series_id") + + if "default_playlist_id" in validated_data: + instance.default_playlist_id = validated_data.get("default_playlist_id") + + if "email" in validated_data: + instance.email = validated_data.get("email") + + if "funding_category" in validated_data: + instance.funding_category = validated_data.get("funding_category") + + if "image" in validated_data: + instance.image = validated_data.get("image") + + if "internal_note" in validated_data: + instance.internal_note = validated_data.get("internal_note") + + if "is_active" in validated_data: + instance.is_active = validated_data.get("is_active") + + if "is_public" in validated_data: + instance.is_public = validated_data.get("is_public") + + if "logo" in validated_data: + instance.logo = validated_data.get("logo") + + if "predecessor" in validated_data: + instance.predecessor = validated_data.get("predecessor") + + if "slug" in validated_data: + instance.slug = validated_data.get("slug") + + if "type" in validated_data: + instance.type = validated_data.get("type") # optional many-to-many - if category := validated_data.get("category"): - instance.category.set(category) + if "category" in validated_data: + instance.category.set(validated_data.get("category", [])) - if hosts := validated_data.get("hosts"): - instance.hosts.set(hosts) + if "hosts" in validated_data: + instance.hosts.set(validated_data.get("hosts", [])) - if language := validated_data.get("language"): - instance.language.set(language) + if "language" in validated_data: + instance.language.set(validated_data.get("language", [])) - if music_focus := validated_data.get("music_focus"): - instance.music_focus.set(music_focus) + if "music_focus" in validated_data: + instance.music_focus.set(validated_data.get("music_focus", [])) - if owners := validated_data.get("owners"): - instance.owners.set(owners) + if "owners" in validated_data: + instance.owners.set(validated_data.get("owners", [])) - if topic := validated_data.get("topic"): - instance.topic.set(topic) + if "topic" in validated_data: + instance.topic.set(validated_data.get("topic", [])) # optional nested objects if links_data := validated_data.get("links"): @@ -842,12 +895,10 @@ class TimeSlotSerializer(serializers.ModelSerializer): note_id = serializers.SerializerMethodField() show_id = serializers.SerializerMethodField() schedule_id = serializers.PrimaryKeyRelatedField( - queryset=Schedule.objects.all(), required=False + queryset=Schedule.objects.all(), required=False, source="schedule" ) repetition_of_id = serializers.PrimaryKeyRelatedField( - allow_null=True, - queryset=TimeSlot.objects.all(), - required=False, + allow_null=True, queryset=TimeSlot.objects.all(), required=False, source="repetition_of" ) class Meta: @@ -877,12 +928,17 @@ class TimeSlotSerializer(serializers.ModelSerializer): def update(self, instance, validated_data): """Update and return an existing Show instance, given the validated data.""" - # Only save certain fields - instance.memo = validated_data.get("memo", instance.memo) - instance.repetition_of = validated_data.get("repetition_of_id", instance.repetition_of) - instance.playlist_id = validated_data.get("playlist_id", instance.playlist_id) + if "memo" in validated_data: + instance.memo = validated_data.get("memo") + + if "repetition_of" in validated_data: + instance.repetition_of = validated_data.get("repetition_of") + + if "playlist_id" in validated_data: + instance.playlist_id = validated_data.get("playlist_id") instance.save() + return instance @@ -905,7 +961,7 @@ class NoteSerializer(serializers.ModelSerializer): source="contributors", ) image_id = serializers.PrimaryKeyRelatedField( - queryset=Image.objects.all(), required=False, allow_null=True + queryset=Image.objects.all(), required=False, allow_null=True, source="image" ) language_ids = serializers.PrimaryKeyRelatedField( allow_null=True, @@ -918,7 +974,7 @@ class NoteSerializer(serializers.ModelSerializer): playlist_id = serializers.IntegerField(required=False) tags = JSONSchemaField(tags_json_schema, required=False) timeslot_id = serializers.PrimaryKeyRelatedField( - queryset=TimeSlot.objects.all(), required=False + queryset=TimeSlot.objects.all(), required=False, source="timeslot" ) topic_ids = serializers.PrimaryKeyRelatedField( allow_null=True, many=True, queryset=Topic.objects.all(), required=False, source="topic" @@ -973,7 +1029,7 @@ class NoteSerializer(serializers.ModelSerializer): user_is_owner = user in show.owners.all() # Only superusers and owners of a show are allowed to create a note - # Being a privileged user overrides the ownership + # Being a superuser overrides the ownership if not (user.is_superuser or user_is_owner): raise exceptions.PermissionDenied( detail="You are not allowed to create a note for this show." @@ -984,7 +1040,7 @@ class NoteSerializer(serializers.ModelSerializer): language = validated_data.pop("language", show.language.values_list("id", flat=True)) topic = validated_data.pop("topic", show.topic.values_list("id", flat=True)) - # optional + # optional foreign key validated_data["image"] = validated_data.pop("image_id", None) note = Note.objects.create( @@ -996,10 +1052,7 @@ class NoteSerializer(serializers.ModelSerializer): note.language.set(language) note.topic.set(topic) - if cba_id := validated_data.get("cba_id"): - if audio_url := get_audio_url(cba_id): - NoteLink.objects.create(note=note, type="CBA", url=audio_url) - + # optional nested objects for link_data in links_data: NoteLink.objects.create(note=note, **link_data) @@ -1019,34 +1072,47 @@ class NoteSerializer(serializers.ModelSerializer): user_is_owner = user in instance.timeslot.schedule.show.owners.all() # Only superusers and owners of a show are allowed to update a note - # Being a privileged user overrides the ownership + # Being a superuser overrides the ownership if not (user.is_superuser or user_is_owner): raise exceptions.PermissionDenied(detail="You are not allowed to update this note.") - instance.cba_id = validated_data.get("cba_id", instance.cba_id) - instance.content = validated_data.get("content", instance.content) - instance.image = validated_data.get("image_id", instance.image) - instance.slug = validated_data.get("slug", instance.slug) - instance.summary = validated_data.get("summary", instance.summary) - instance.timeslot = validated_data.get("timeslot_id", instance.timeslot) - instance.tags = validated_data.get("tags", instance.tags) - instance.title = validated_data.get("title", instance.title) + print(validated_data) + if "cba_id" in validated_data: + instance.cba_id = validated_data.get("cba_id") + + if "content" in validated_data: + instance.content = validated_data.get("content") + + if "image" in validated_data: + instance.image = validated_data.get("image") + + if "slug" in validated_data: + instance.slug = validated_data.get("slug") + + if "summary" in validated_data: + instance.summary = validated_data.get("summary") + + if "timeslot" in validated_data: + instance.timeslot = validated_data.get("timeslot") + + if "tags" in validated_data: + instance.tags = validated_data.get("tags") + + if "title" in validated_data: + instance.title = validated_data.get("title") # optional many-to-many - if contributors := validated_data.get("contributors"): - instance.contributors.set(contributors) + if "contributors" in validated_data: + instance.contributors.set(validated_data.get("contributors", [])) - if language := validated_data.get("language"): - instance.language.set(language) + if "language" in validated_data: + instance.language.set(validated_data.get("language", [])) # Only update this field if the user is superuser, ignore otherwise - if (topic := validated_data.get("topic")) and user.is_superuser: - instance.topic.set(topic) - - if cba_id := validated_data.get("cba_id"): - if audio_url := get_audio_url(cba_id): - NoteLink.objects.create(note=instance, type="CBA", url=audio_url) + if "topic" in validated_data and user.is_superuser: + instance.topic.set(validated_data.get("topic", [])) + # optional nested objects if links_data := validated_data.get("links"): instance = delete_links(instance) -- GitLab