反序列化进阶使用

准备工作

定义2个ModelSerializer

from rest_framework import serializers
from book.models import PeopleInfo,BookInfo
class PeopleInfoModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = PeopleInfo
        fields = ['id']


class BookInfoModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = BookInfo
        fields = '__all__'

1.保存1个人物信息

1.1前端传递的数据如下所示

data = {
    'book':1,
    'name': '靖哥哥',
    'password': '123456abc',
}

我们该定义什么样的序列化器?

定义的序列化器为

from rest_framework import serializers
from book.models import PeopleInfo
class PeopleInfoModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = PeopleInfo
        fields = ['id','book','name','password']
        extra_kwargs = {
            'password': {'write_only':True}
        }

结论

write_only表明该字段仅用于反序列化输入。在序列化输出时忽略该字段。

1.2前端传递的数据如下所示

data = {
    'book_id':1,
    'name': '靖哥哥',
    'password': '123456abc'
}

我们该定义什么样的序列化器?

定义的序列化为

from rest_framework import serializers
from book.models import PeopleInfo
class PeopleInfoModelSerializer(serializers.ModelSerializer):
    book_id=serializers.IntegerField()

    class Meta:
        model = PeopleInfo
        fields = ['id','book_id','name','password']
        extra_kwargs = {
            'password': {'write_only':True}
        }

或者

from rest_framework import serializers
from book.models import PeopleInfo
class PeopleInfoModelSerializer(serializers.ModelSerializer):
    book_id=serializers.IntegerField(required=False)
    book=serializers.StringRelatedField()

    class Meta:
        model = PeopleInfo
        fields = ['id','book_id','book','name','password']
        extra_kwargs = {
            'password': {'write_only':True}
        }

结论

外键book或者book_id都可以保存数据。主要看前端传递过来的数据形式

1.3前端传递的数据如下所示

data = {
    'book_id':1,
    'name': '靖哥哥',
    'password': '123456abc',
    'is_delete': 1
}

我们该定义什么样的序列化器?

定义的序列化为

from rest_framework import serializers
from book.models import PeopleInfo,BookInfo
class PeopleInfoModelSerializer(serializers.ModelSerializer):
    book_id=serializers.IntegerField(required=False)
    book=serializers.StringRelatedField()

    class Meta:
        model = PeopleInfo
        fields = ['id','book_id','book','name','password','is_delete']
        extra_kwargs = {
            'password': {'write_only':True},
            'is_delete': {'read_only':True}
        }

结论

read_only表明该字段仅用于序列化输出。反序列化时忽略次字段。

1.4前端传递的数据如下所示

data = {
    'book_id':1,
    'name': '靖哥哥',
    'password': '123456abc',
    'description': '描述',
    'is_delete': 1
}

如果定义的序列化为以下代码。会出现什么问题?

from rest_framework import serializers
from book.models import PeopleInfo,BookInfo
class PeopleInfoModelSerializer(serializers.ModelSerializer):
    book_id=serializers.IntegerField(required=False)
    book=serializers.StringRelatedField()

    class Meta:
        model = PeopleInfo
        fields = ['id','book_id','book','name','password','is_delete']
        extra_kwargs = {
            'password': {'write_only':True},
            'is_delete': {'read_only':True}
        }

结论

description没有在序列化器中定义字段。如果需要验证或保存某一个字段是必须要在序列化器中定义该字段

2.保存n个人物信息

前端传递的数据如下所示

[
    {
        'book_id': 1,
        'name': '靖妹妹~~~',
        'password':'123456abc'
    },
    {
        'book_id': 1,
        'name': '靖表哥~~~',
        'password': '123456abc'
    }
]

定义的序列化器为

from rest_framework import serializers
from book.models import PeopleInfo
class PeopleInfoModelSerializer(serializers.ModelSerializer):
    book_id=serializers.IntegerField(required=False)
    book=serializers.StringRelatedField()

    class Meta:
        model = PeopleInfo
        fields = ['id','book_id','book','name','password','is_delete']
        extra_kwargs = {
            'password': {'write_only':True},
            'is_delete': {'read_only':True}
        }

结论

进行反序列化也可以保存字典列表,需要设置many=True

3.保存1本新书籍和n个新人物信息

前端传递的数据如下所示

{
    'name':'离离原上草',
    'people':[
        {
            'name': '靖妹妹111',
            'password': '123456abc'
        },
        {
            'name': '靖表哥222',
            'password': '123456abc'
        }
    ]
}

我们该定义什么样的序列化器?

定义的序列化器为

from rest_framework import serializers
from book.models import PeopleInfo,BookInfo
class PeopleInfoModelSerializer(serializers.ModelSerializer):
    book_id=serializers.IntegerField(required=False)
    book=serializers.StringRelatedField()

    class Meta:
        model = PeopleInfo
        fields = ['id','book_id','book','name','password','is_delete']
        extra_kwargs = {
            'password': {'write_only':True},
            'is_delete': {'read_only':True}
        }

class BookInfoModelSerializer(serializers.ModelSerializer):
    people=PeopleInfoModelSerializer(many=True)
    class Meta:
        model = BookInfo
        fields = '__all__'


    def create(self, validated_data):

        people=validated_data.pop('people')

        book=BookInfo.objects.create(**validated_data)

        for person in people:
            PeopleInfo.objects.create(book=book,**person)

        return book

档说

默认情况下,嵌套串行器是只读的。如果要支持对嵌套序列化器字段的写操作,则需要创建create()update()方法,以明确指定应如何保存数据。

需要我们在新增数据时,实现create方法