diff --git a/program/serializers.py b/program/serializers.py index 40679801918d5ebb594dba3a614116c9c6a30e12..690b42a0e252cf06fa543367eae3fe71caff260e 100644 --- a/program/serializers.py +++ b/program/serializers.py @@ -385,28 +385,38 @@ class ShowLinkSerializer(serializers.ModelSerializer): class ShowSerializer(serializers.HyperlinkedModelSerializer): - category = serializers.PrimaryKeyRelatedField(queryset=Category.objects.all(), many=True) - funding_category = serializers.PrimaryKeyRelatedField(queryset=FundingCategory.objects.all()) - hosts = serializers.PrimaryKeyRelatedField(queryset=Host.objects.all(), many=True) - image = serializers.PrimaryKeyRelatedField( - allow_null=True, - queryset=Image.objects.all(), - required=False, + category_ids = serializers.PrimaryKeyRelatedField( + many=True, queryset=Category.objects.all(), source="category" + ) + funding_category_id = serializers.PrimaryKeyRelatedField( + queryset=FundingCategory.objects.all() + ) + 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 + ) + language_ids = serializers.PrimaryKeyRelatedField( + many=True, queryset=Language.objects.all(), source="language" ) - language = serializers.PrimaryKeyRelatedField(queryset=Language.objects.all(), many=True) links = HostLinkSerializer(many=True, required=False) - logo = serializers.PrimaryKeyRelatedField( - allow_null=True, - queryset=Image.objects.all(), - required=False, + logo_id = serializers.PrimaryKeyRelatedField( + allow_null=True, queryset=Image.objects.all(), required=False + ) + music_focus_ids = serializers.PrimaryKeyRelatedField( + many=True, queryset=MusicFocus.objects.all(), source="music_focus" ) - music_focus = serializers.PrimaryKeyRelatedField(queryset=MusicFocus.objects.all(), many=True) - owners = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), many=True) - predecessor = serializers.PrimaryKeyRelatedField( - queryset=Show.objects.all(), required=False, allow_null=True + owner_ids = serializers.PrimaryKeyRelatedField( + many=True, queryset=User.objects.all(), source="owners" ) - topic = serializers.PrimaryKeyRelatedField(queryset=Topic.objects.all(), many=True) - type = serializers.PrimaryKeyRelatedField(queryset=Type.objects.all()) + predecessor_id = serializers.PrimaryKeyRelatedField( + allow_null=True, queryset=Show.objects.all(), required=False + ) + topic_ids = serializers.PrimaryKeyRelatedField( + many=True, queryset=Topic.objects.all(), source="topic" + ) + type_id = serializers.PrimaryKeyRelatedField(queryset=Type.objects.all()) class Meta: model = Show @@ -417,29 +427,29 @@ class ShowSerializer(serializers.HyperlinkedModelSerializer): "updated_by", ) fields = ( - "category", + "category_ids", "cba_series_id", "default_playlist_id", "description", "email", - "funding_category", - "hosts", + "funding_category_id", + "host_ids", "id", - "image", + "image_id", "internal_note", "is_active", "is_public", - "language", + "language_ids", "links", - "logo", - "music_focus", + "logo_id", + "music_focus_ids", "name", - "owners", - "predecessor", + "owner_ids", + "predecessor_id", "short_description", "slug", - "topic", - "type", + "topic_ids", + "type_id", ) + read_only_fields def create(self, validated_data): @@ -455,8 +465,18 @@ class ShowSerializer(serializers.HyperlinkedModelSerializer): music_focus = validated_data.pop("music_focus") links_data = validated_data.pop("links", []) + # required + validated_data["funding_category"] = validated_data.pop("funding_category_id") + validated_data["type"] = validated_data.pop("type_id") + + # optional + validated_data["image"] = validated_data.pop("image_id", None) + validated_data["logo"] = validated_data.pop("logo_id", None) + validated_data["predecessor"] = validated_data.pop("predecessor_id", None) + show = Show.objects.create( - created_by=self.context.get("request").user.username, **validated_data + created_by=self.context.get("request").user.username, + **validated_data, ) # Save many-to-many relationships @@ -486,20 +506,20 @@ class ShowSerializer(serializers.HyperlinkedModelSerializer): instance.description = validated_data.get("description", instance.description) instance.email = validated_data.get("email", instance.email) instance.funding_category = validated_data.get( - "funding_category", instance.funding_category + "funding_category_id", instance.funding_category ) - instance.image = validated_data.get("image", instance.image) + 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", instance.logo) + instance.logo = validated_data.get("logo_id", instance.logo) instance.name = validated_data.get("name", instance.name) - instance.predecessor = validated_data.get("predecessor", instance.predecessor) + instance.predecessor = validated_data.get("predecessor_id", instance.predecessor) instance.short_description = validated_data.get( "short_description", instance.short_description ) instance.slug = validated_data.get("slug", instance.slug) - instance.type = validated_data.get("type", instance.type) + instance.type = validated_data.get("type_id", instance.type) instance.category.set(validated_data.get("category", instance.category)) instance.hosts.set(validated_data.get("hosts", instance.hosts)) @@ -544,8 +564,8 @@ class ScheduleSerializer(serializers.ModelSerializer): "id", "is_repetition", "last_date", - "rrule", - "show", + "rrule_id", + "show_id", "start_time", ) @@ -577,20 +597,18 @@ class ScheduleInRequestSerializer(ScheduleSerializer): "first_date", "is_repetition", "last_date", - "rrule", - "show", + "rrule_id", + "show_id", "start_time", ) def create(self, validated_data): """Create and return a new Schedule instance, given the validated data.""" - rrule = validated_data.pop("rrule") - show = validated_data.pop("show") + validated_data["rrule"] = validated_data.pop("rrule_id") + validated_data["show"] = validated_data.pop("show_id") schedule = Schedule.objects.create(**validated_data) - schedule.rrule = rrule - schedule.show = show schedule.save() return schedule @@ -607,8 +625,8 @@ class ScheduleInRequestSerializer(ScheduleSerializer): instance.default_playlist_id = validated_data.get( "default_playlist_id", instance.default_playlist_id ) - instance.rrule = validated_data.get("rrule", instance.rrule) - instance.show = validated_data.get("show", instance.show) + instance.rrule = validated_data.get("rrule_id", instance.rrule) + instance.show = validated_data.get("show_id", instance.show) instance.add_days_no = validated_data.get("add_days_no", instance.add_days_no) instance.add_business_days_only = validated_data.get( "add_business_days_only", instance.add_business_days_only @@ -623,10 +641,10 @@ class CollisionSerializer(serializers.Serializer): start = serializers.DateTimeField() end = serializers.DateTimeField() playlist_id = serializers.IntegerField(allow_null=True) - show = serializers.IntegerField() + show_id = serializers.IntegerField() show_name = serializers.CharField() repetition_of = serializers.IntegerField(allow_null=True) - schedule = serializers.IntegerField() + schedule_id = serializers.IntegerField() memo = serializers.CharField() note_id = serializers.IntegerField(allow_null=True) @@ -642,11 +660,13 @@ class ProjectedTimeSlotSerializer(serializers.Serializer): class DryRunTimeSlotSerializer(serializers.Serializer): id = serializers.PrimaryKeyRelatedField(queryset=TimeSlot.objects.all(), allow_null=True) - schedule = serializers.PrimaryKeyRelatedField(queryset=Schedule.objects.all(), allow_null=True) + schedule_id = serializers.PrimaryKeyRelatedField( + queryset=Schedule.objects.all(), allow_null=True + ) playlist_id = serializers.IntegerField(allow_null=True) start = serializers.DateField() end = serializers.DateField() - repetition_of = serializers.IntegerField(allow_null=True) + repetition_of_id = serializers.IntegerField(allow_null=True) memo = serializers.CharField() @@ -678,9 +698,11 @@ class ScheduleDryRunResponseSerializer(serializers.Serializer): class TimeSlotSerializer(serializers.ModelSerializer): - show = serializers.PrimaryKeyRelatedField(queryset=Show.objects.all(), required=False) - schedule = serializers.PrimaryKeyRelatedField(queryset=Schedule.objects.all(), required=False) - repetition_of = serializers.PrimaryKeyRelatedField( + show_id = serializers.PrimaryKeyRelatedField(queryset=Show.objects.all(), required=False) + schedule_id = serializers.PrimaryKeyRelatedField( + queryset=Schedule.objects.all(), required=False + ) + repetition_of_id = serializers.PrimaryKeyRelatedField( allow_null=True, queryset=TimeSlot.objects.all(), required=False, @@ -691,14 +713,14 @@ class TimeSlotSerializer(serializers.ModelSerializer): read_only_fields = ( "id", "end", - "schedule", - "show", + "schedule_id", + "show_id", "start", ) fields = ( "memo", "playlist_id", - "repetition_of", + "repetition_of_id", ) + read_only_fields def update(self, instance, validated_data): @@ -706,7 +728,7 @@ class TimeSlotSerializer(serializers.ModelSerializer): # Only save certain fields instance.memo = validated_data.get("memo", instance.memo) - instance.repetition_of = validated_data.get("repetition_of", instance.repetition_of) + instance.repetition_of = validated_data.get("repetition_of", instance.repetition_of_id) instance.playlist_id = validated_data.get("playlist_id", instance.playlist_id) instance.save() return instance @@ -720,11 +742,14 @@ class NoteLinkSerializer(serializers.ModelSerializer): class NoteSerializer(serializers.ModelSerializer): contributors = serializers.PrimaryKeyRelatedField(queryset=Host.objects.all(), many=True) - image = serializers.PrimaryKeyRelatedField( + image_id = serializers.PrimaryKeyRelatedField( queryset=Image.objects.all(), required=False, allow_null=True ) links = NoteLinkSerializer(many=True, required=False) - timeslot = serializers.PrimaryKeyRelatedField(queryset=TimeSlot.objects.all(), required=False) + playlist_id = serializers.IntegerField(required=False) + timeslot_id = serializers.PrimaryKeyRelatedField( + queryset=TimeSlot.objects.all(), required=False + ) class Meta: model = Note @@ -740,14 +765,14 @@ class NoteSerializer(serializers.ModelSerializer): "content", "contributors", "id", - "image", + "image_id", "links", - "owner", - "playlist", + "owner_id", + "playlist_id", "slug", "summary", "tags", - "timeslot", + "timeslot_id", "title", ) + read_only_fields @@ -757,6 +782,12 @@ class NoteSerializer(serializers.ModelSerializer): links_data = validated_data.pop("links", []) contributors = validated_data.pop("contributors", []) + # required + validated_data["timeslot"] = validated_data.pop("timeslot_id") + + # optional + validated_data["image"] = validated_data.pop("image_id", None) + # the creator of the note is the owner note = Note.objects.create( created_by=self.context.get("request").user.username, @@ -791,10 +822,10 @@ class NoteSerializer(serializers.ModelSerializer): 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", instance.image) + instance.image = validated_data.get("image", instance.image_id) instance.slug = validated_data.get("slug", instance.slug) instance.summary = validated_data.get("summary", instance.summary) - instance.timeslot = validated_data.get("timeslot", instance.timeslot) + instance.timeslot = validated_data.get("timeslot", instance.timeslot_id) instance.title = validated_data.get("title", instance.title) instance.contributors.set(validated_data.get("contributors", instance.contributors)) diff --git a/program/services.py b/program/services.py index 480c4aef43b2d4d6a634169165aab59adcf8273d..005192dbc5e03ee064d710ef502c9b03c418ab94 100644 --- a/program/services.py +++ b/program/services.py @@ -47,19 +47,19 @@ class ScheduleData(TypedDict): id: int | None is_repetition: bool | None last_date: str | None - rrule: int - show: int | None + rrule_id: int + show_id: int | None start_time: str class Collision(TypedDict): end: str - id: int + timeslot_id: int memo: str note_id: int | None playlist_id: int | None - schedule: int - show: int + schedule_id: int + show_id: int show_name: str start: str @@ -190,7 +190,7 @@ def resolve_conflicts(data: ScheduleCreateUpdateData, schedule_pk: int | None, s # Delete collision(s) for collision in timeslot["collisions"]: try: - to_delete.append(TimeSlot.objects.get(pk=collision["id"])) + to_delete.append(TimeSlot.objects.get(pk=collision["timeslot_id"])) except ObjectDoesNotExist: pass @@ -212,7 +212,7 @@ def resolve_conflicts(data: ScheduleCreateUpdateData, schedule_pk: int | None, s ), ) - existing_ts = TimeSlot.objects.get(pk=existing["id"]) + existing_ts = TimeSlot.objects.get(pk=existing["timeslot_id"]) existing_ts.start = parse_datetime(timeslot["end"]) to_update.append(existing_ts) @@ -232,7 +232,7 @@ def resolve_conflicts(data: ScheduleCreateUpdateData, schedule_pk: int | None, s ), ) - existing_ts = TimeSlot.objects.get(pk=existing["id"]) + existing_ts = TimeSlot.objects.get(pk=existing["timeslot_id"]) existing_ts.end = parse_datetime(timeslot["start"]) to_update.append(existing_ts) @@ -260,7 +260,7 @@ def resolve_conflicts(data: ScheduleCreateUpdateData, schedule_pk: int | None, s ), ) - existing_ts = TimeSlot.objects.get(pk=existing["id"]) + existing_ts = TimeSlot.objects.get(pk=existing["timeslot_id"]) existing_ts.end = parse_datetime(timeslot["start"]) to_update.append(existing_ts) @@ -366,7 +366,7 @@ def instantiate_upcoming_schedule( If the data does not contain a last_date, the Schedule instance will not contain a last_date. """ - rrule = RRule.objects.get(pk=data["rrule"]) + rrule = RRule.objects.get(pk=data["rrule_id"]) show = Show.objects.get(pk=show_pk) is_repetition = data["is_repetition"] if "is_repetition" in data else False @@ -635,13 +635,13 @@ def generate_conflicts(timeslots: list[TimeSlot]) -> Conflicts: for c in collision_list: # Add the collision collision = { - "id": c.id, + "timeslot_id": c.id, "start": str(c.start), "end": str(c.end), "playlist_id": c.playlist_id, - "show": c.show.id, + "show_id": c.show.id, "show_name": c.show.name, - "schedule": c.schedule_id, + "schedule_id": c.schedule_id, "memo": c.memo, }