Django REST Framework - SerializerMethodField является пустым на serializer.save () - PullRequest
0 голосов
/ 11 декабря 2018

Я использую Django и REST Framework.Я хочу сохранить с сериализатором по данным.Я позвонил на serializer.save().Но поле сохраненной модели пусто с полем animal в HumanSerializer.Я хочу определить animal поле по SerializerMethodField и хочу сохранить модель.Как это сделать?

Сериализатор:

class HumanSerializer(serializers.ModelSerializer):

    animal = SerializerMethodField()

    class Meta:
        model = Human
        fields = (
            'id',
            'animal', # <- animal is ForeignKey of Animal model
        )

    def get_animal(self, lead):
        # blah blah blah
        pass

Процесс сохранения:

data['animal'] = 1
serializer = HumanSerializer(
    data=data,
    context={'request': request},
)
if serializer.is_valid():
    human = serializer.save()
    human.animal # <- animal is null. but delete SerializerMethodField then not null

Ответы [ 3 ]

0 голосов
/ 11 декабря 2018

SerializerMethodField всегда поле только для чтения.Вы можете добавить другое поле для написания.

Пример :

class HumanSerializer(serializers.ModelSerializer):

    animal = SerializerMethodField()
    animal_id = serializers.PrimaryKeyRelatedField(
        source='animal',
        queryset=Animal.objects.all(),
        write_only=True
    )

    class Meta:
        model = Human
        fields = (
            'id',
            'animal',
            'animal_id'
        )

Затем передайте animal_id в данных запроса, чтобы сохранить Animal вместес Human.

Ref :
* PrimaryKeyRelatedField docs

0 голосов
/ 12 декабря 2018

SerializerMethodField только для чтения по умолчанию.Поэтому, когда ваш сериализатор проверяет данные, он извлекает ключ «животного» из данных для сохранения в модели.

Чтобы преодолеть это, можно переопределить функцию проверки сериализатора, чтобы он не удалял ключ животного изваши данные.Пример:

class HumanSerializer(serializers.ModelSerializer):


    animal = SerializerMethodField()


    def validate(self, data):
        animal = data['animal']
        # Any validation code for animal, if required
        validated_data = super(HumanSerializer, self).validate(data)
        validated_data['animal'] = animal
        return validated_data


    class Meta:
        model = Human
        fields = (
            'id',
            'animal',  # <- animal is ForeignKey of Animal model
        )


    def get_animal(self, lead):
        # blah blah blah
        pass
0 голосов
/ 11 декабря 2018

Во-первых, SerializerMethodField только для чтения.Таким образом, вы не можете использовать его для принятия человеческих данных.Во-вторых, создание вложенных объектов по умолчанию не может быть обработано сериализатором.У вас есть переопределить метод create и обработать создание вложенных объектов.Ознакомьтесь с документами о том, как реализовать записываемые вложенные сериализаторы

...