Search code examples
djangodjango-rest-frameworkserializationdjango-rest-viewsetsnest-nested-object

Saving two related models via one serializer and passing the first id to the second as a foreign key in django rest framework?


I have a JourneySchedule model which stores depart and return journeys:

class JouaneySchedule(models.Model):
  Owner = models.ForeignKey('Profile', on_delete=models.PROTECT)
  ReturnOf = models.ForeignKey('self', on_delete=models.CASCADE, null=True)
  JourneyDate = models.DateField(null=True)
  JourneyStartTime = models.TimeField()
  IsDepart = models.BooleanField(default=True)
  Fare = models.PositiveIntegerField(null=False, default=0)

Depart and return journeys are connected via ReturnOf self foreign key.

Journey serializer is:

class JourneyScheduleSerializer(serializers.ModelSerializer):
Owner = serializers.ReadOnlyField(source='user.id')
ReturnOf = serializers.ReadOnlyField()

class Meta:
    model = JourneySchedule
    fields = (
        'id',
        'Driver',
        'ReturnOf',
        'JourneyDate',
        'JourneyStartTime',
        'IsDepart',
        'Fare'
    )

I have defined Commute model to save depart and return journeys at once using nested object (both are instances of journey)

class CommuteSerializer(serializers.Serializer):
    depart_journey = JourneyScheduleSerializer(required=False)
    return_journey = JourneyScheduleSerializer(required=False)

    class Meta:
        model = JourneySchedule
        fields = ('depart_journey', 'return_journey')

So I need to save depart_journey first and then pass the id to return_journey as ReturnOf field. How can I achieve that?


Solution

  • You need to override create method of CommuteSerializer for it, something like this:

    from collections import namedtuple
    
    class CommuteSerializer(serializers.SerializerSerializer):
        depart_journey = JourneyScheduleSerializer(required=False)
        return_journey = JourneyScheduleSerializer(required=False)
    
        def create(self, validated_data):
            depart_journey = validated_data['depart_journey']
            return_journey = validated_data['return_journey']
            depart_object = JourneySchedule.objects.create(**depart_journey)
            return_object = JourneySchedule.objects.create(ReturnOf=depart_object, **return_journey)
            commute = namedtuple('commute', ['depart_journey', 'return_journey'])
            return commute(depart_journey=depart_journey, return_journey=depart_object)