Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest framework Serialize many to many field

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

like image 464
Jack Avatar asked May 03 '18 20:05

Jack


People also ask

What is the difference between ModelSerializer and HyperlinkedModelSerializer?

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.

Why serializers are used in django?

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.

What is many true in serializer django?

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)


Video Answer


1 Answers

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__',)
like image 87
Andrea Corbellini Avatar answered Sep 21 '22 09:09

Andrea Corbellini