Фреймворк Django Rest Сериализация поля «многие ко многим»

Я пытаюсь сериализовать полезную нагрузку json, которая имеет поле с массивом, проверка .is_valid() возвращает true, но я получаю KeyError: 'passengers', когда пытаюсь сделать это serializer.data['passengers'], но другие поля работают нормально (например, booking_number и статус).

Это response.data, который я передаю сериализатору:

{'booking_number': 2839, 'passengers': [{'first_name': 'Jack', 'surname': 'Smith', 'email': '[email protected]', 'phone_number': '1234'}], 'status': 'ON_HOLD'} 

Мои серализаторы:

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')

Мои модели:

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()  

Будем очень признательны за любые советы о том, как заставить эту работу работать.

Кстати, я следил за этим: Django rest framework, сериализующий многие ко многим полям


person Jack    schedule 03.05.2018    source источник


Ответы (1)


Если вам нужно десериализовать поля, вы не должны использовать read_only=True:

class FindBus(serializers.ModelSerializer):
    passengers = PassengerSerializer(many=True)
    ...

Обратите внимание, что этого будет недостаточно для сохранения отношений m2m: как описано в Вложенные сериализаторы с возможностью записи, вам также потребуется определить методы create() и/или update() в вашем сериализаторе:

class FindBus(serializers.ModelSerializer):
    passengers = PassengerSerializer(many=True)
    ...

    def create(self, validated_data):
        ...

    def update(self, validated_data):
        ...

Причина необходимости использования create/update заключается в том, что вам нужно решить, относятся ли получаемые вами сведения о пассажире к существующим объектам или их необходимо создать.

Вам также может понадобиться добавить fields = ('__all__',) (или указать интересующие вас поля) к вашему PassengerSerializer:

class PassengerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Passenger
        fields = ('__all__',)
person Andrea Corbellini    schedule 03.05.2018
comment
Добавление полей = ('все') и удаление только для чтения сделали свое дело. Спасибо за дополнительную информацию. - person Jack; 04.05.2018