关联对象嵌套序列化-Python-三大框架课件

关联对象嵌套序列化如果需要序列化的数据中包含有其他关联对象,则对关联对象数据的序列化需要指明。例如,在定义人物数据的序列化器时,外键book(即所属的图书)字段如何序列化?我们先定义PeopleInfoSerialzier除外键字段外的其他部分class PeopleInfoSerializer(serializers.Serializer): """英雄数据序列化器""" GENDER_CHOICES = ( (0, 'male'), (1, 'female') ) id = serializers.IntegerField(label='ID', read_only=True) name = serializers.CharField(label='名字', max_length=20) gender = serializers.ChoiceField(choices=GENDER_CHOICES, label='性别', required=False) description = serializers.CharField(label='描述信息', max_length=200, required=False, allow_null=True)对于关联字段,可以采用以下几种方式: 1) PrimaryKeyRelatedField此字段将被序列化为关联对象的主键。 book = serializers.PrimaryKeyRelatedField(label='图书',read_only=True)或者book = serializers.PrimaryKeyRelatedField(label='图书',queryset=BookInfo.objects.all())指明字段时需要包含read_only=True或者queryset参数: 1.包含read_only=True参数时,该字段将不能用作反序列化使用2.包含queryset参数时,将被用作反序列化时参数校验使用使用效果: >>> from book.models import PeopleInfo >>> from book.serializers import PeopleInfoSerializer >>> person = PeopleInfo.objects.get(id=10) >>> serializer = PeopleInfoSerializer(instance=person) >>> serializer.data {'id': 10, 'book': 3, 'description': '独孤九剑', 'gender': 1, 'name': '令狐冲'} 2) StringRelatedField此字段将被序列化为关联对象的字符串表示方式(即__str__方法的返回值) book = serializers.StringRelatedField(label='图书')使用效果>>> from book.models import PeopleInfo >>> from book.serializers import PeopleInfoSerializer >>> person = PeopleInfo.objects.get(id=10) >>> serializer = PeopleInfoSerializer(instance=person) >>> serializer.data {'description': '独孤九剑', 'name': '令狐冲', 'gender': 1, 'book': '笑傲江湖', 'id': 10} 3)使用关联对象的序列化器book = BookInfoSerializer()使用效果>>> from book.models import PeopleInfo >>> from book.serializers import PeopleInfoSerializer >>> person = PeopleInfo.objects.get(id=10) >>> serializer = PeopleInfoSerializer(instance=person) >>> serializer.data {'book': OrderedDict([('id', 3), ('name', '笑傲江湖'), ('pub_date', '1995-12-24'), ('readcount', 28), ('commentcount', ('image', None)]), 'gender': 1, 'name': '令狐冲', 'description': '独孤九剑', 'id': 10} 4)HyperlinkedRelatedField此字段将被序列化为获取关联对象数据的接口链接book = serializers.HyperlinkedRelatedField(label='图书', read_only=True, view_name='book-detail')必须指明view_name参数,以便DRF根据视图名称寻找路由,进而拼接成完整URL。使用效果{'description': '独孤九剑', 'name': '令狐冲', 'gender': 1, 'book': 'http://127.0.0.1/books/2/', 'id': 10}我们暂时还没有定义视图,此方式不再演示。 5)SlugRelatedField此字段将被序列化为关联对象的指定字段数据book = serializers.SlugRelatedField(label='图书', read_only=True, slug_field='pub_date') slug_field指明使用关联对象的哪个字段使用效果>>> from book.models import PeopleInfo >>> from book.serializers import PeopleInfoSerializer >>> person = PeopleInfo.objects.get(id=10) >>> serializer = PeopleInfoSerializer(instance=person) >>> serializer.data {'book': datetime.date(1995, 12, 24), 'description': '独孤九剑', 'name': '令狐冲', 'id': 10, 'gender': 1} 6)重写to_representation方法序列化器的每个字段实际都是由该字段类型的to_representation方法决定格式的,可以通过重写该方法来决定格式。注意,to_representations方法不仅局限在控制关联对象格式上,适用于各个序列化器字段类型。自定义一个新的关联字段: class BookRelateField(serializers.RelatedField): """自定义用于处理图书的字段""" def to_representation(self, value): return 'Book: %d %s' % (value.id, value.name)指明book为BookRelateField类型book = BookRelateField(read_only=True)使用效果>>> from book.models import PeopleInfo >>> from book.serializers import PeopleInfoSerializer >>> person = PeopleInfo.objects.get(id=10) >>> serializer = PeopleInfoSerializer(instance=person) >>> serializer.data {'description': '独孤九剑', 'book': 'Book: 3笑傲江湖', 'id': 10, 'name': '令狐冲', 'gender': 1} many参数如果关联的对象数据不是只有一个,而是包含多个数据,如想序列化图书BookInfo数据,每个BookInfo对象关联的英雄PeopleInfo对象可能有多个,此时关联字段类型的指明仍可使用上述几种方式,只是在声明关联字段时,多补充一个many=True参数即可。此处仅拿PrimaryKeyRelatedField类型来举例,其他相同。在BookInfoSerializer中添加关联字段: class BookInfoSerializer(serializers.Serializer): """图书数据序列化器""" id = serializers.IntegerField(label='ID', read_only=True) name = serializers.CharField(label='名称', max_length=20) pub_date = serializers.DateField(label='发布日期', required=False) readcount = serializers.IntegerField(label='阅读量', required=False) commentcount = serializers.IntegerField(label='评论量', required=False) image = serializers.ImageField(label='图片', required=False) peopleinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) #新增使用效果: >>> from book.models import BookInfo >>> from book.serializers import BookInfoSerializer >>> book = BookInfo.objects.get(id=3) >>> serializer = BookInfoSerializer(book) >>> serializer.data {'id': 3, 'peopleinfo_set': [10, 11, 12, 13], 'commentcount': 18, 'name': '笑傲江湖', 'readcount': 28,
ppt 文件大小:14.19MB