Django REST Framework-Serializer.save()上的SerializerMethodField为null

时间:2018-12-11 14:44:02

标签: django python-3.x django-rest-framework

我正在使用Django和REST Framework。我想通过数据与序列化器一起保存。我打电话给serializer.save()。但是保存的模型字段为空,而animal中的HumanSerializer字段为null。我想通过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 :(得分:2)

UIStackView始终是只读字段。您可以添加另一个字段以用于写作。

示例

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_idAnimal一起保存。

参考
* PrimaryKeyRelatedField docs

答案 1 :(得分:1)

首先,SerializerMethodField在设计上是只读的。因此,您不能使用它来接受人员数据。其次,默认情况下,序列化程序无法处理嵌套对象的创建。您可以重写create方法并处理嵌套对象的创建。查看有关如何实现writable nested serializers

的文档

答案 2 :(得分:0)

SerializerMethodField默认为只读。因此,当您的序列化程序将验证数据时,它将从数据中剔除“动物”密钥以保存到模型中。

要克服此问题,一种方法是重写序列化程序的validate函数,以使它不会从数据中删除动物密钥。示例:

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