I am trying to serialise a json payload that has a field with an array, the .is_valid()
check is returning true but I am getting KeyError: 'passengers'
when I try to do this serializer.data['passengers']
but the other fields work fine (such as booking_number and status).
This is the response.data I am passing to the seralizer:
{'booking_number': 2839, 'passengers': [{'first_name': 'Jack', 'surname': 'Smith', 'email': '[email protected]', 'phone_number': '1234'}], 'status': 'ON_HOLD'}
My seralizers:
class PassengerSerializer(serializers.ModelSerializer):
class Meta:
model = Passenger
class FindBus(serializers.ModelSerializer):
passengers = PassengerSerializer(read_only=True, many=True)
class Meta:
model = Booking
fields = ('booking_number', 'passengers', 'status')
My models:
class Passenger(models.Model):
first_name = models.CharField(max_length=25)
surname = models.CharField(max_length=25)
email = models.EmailField()
phone_number = models.CharField(max_length=12)
class Booking(models.Model):
booking_number = models.IntegerField(unique=True)
passenger = models.ManyToManyField(Passenger)
status = models.CharField(max_length=10)
hold_time = models.DateTimeField()
Any advise on how to get this working would be greatly appreciated.
Btw I was following this: Django rest framework serializing many to many field
The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.
Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON , XML or other content types.
by setting many=True you tell drf that queryset contains mutiple items (a list of items) so drf needs to serialize each item with serializer class (and serializer.data will be a list) if you don't set this argument it means queryset is a single instance and serializer.data will be a single object)
If you need to de-serialize fields, you should not use read_only=True
:
class FindBus(serializers.ModelSerializer):
passengers = PassengerSerializer(many=True)
...
Note that this won't be enough for saving m2m relationships: as explained in Writable nested serializers, you'll also need to define create()
and/or update()
methods on your serializer:
class FindBus(serializers.ModelSerializer):
passengers = PassengerSerializer(many=True)
...
def create(self, validated_data):
...
def update(self, validated_data):
...
The reason for the need of the create
/update
is that you have to decide whether the passenger details that you receive refer to existing objects or need to be created.
You might also need to add fields = ('__all__',)
(or specify the fields you're interested in) to your PassengerSerializer
:
class PassengerSerializer(serializers.ModelSerializer):
class Meta:
model = Passenger
fields = ('__all__',)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With