DRF中序列化器的序列化操作
一.序列化器
1.功能:
序列化操作 :将python类型(模型类对象、模型类对象的列表)转换为 字典
反序列化操作 : 将json 类型 转化为字典
二. 序列化器的使用:
1. 定义序列化器类:
# <1>. 继承自 rest_framework.serializers.py中的 Serializer 类
# <2>. 模型类中需要进行序列化的字段定义在序列化器类中,而且字段名称必须和模型类中的保持一致,否则报错。
from rest_framework import serializers
class BookInfoSerializer(serializers.Serializer)
# 序列化器中的字段,名称与模型类中的一致,需要定义的字段是需要进行序列化的。
id = serializers.IntegerField(label='ID', read_only=True)
btitle = serializers.CharField(label='书名', max_length=20)
bpub_date = serializers.DateField(label='发布日期', required=False)
# 关联属性
# heroinfo_set = ****** 下面单独说明关联属性的定义方法(这个属性在数据表中不体现)
class HeroInfoSerializer(serializers.Serializer):
GENDER_CHOICES = (
(1, '男'),
(0, '女')
)
id = serializers.IntegerField(label='ID', read_only=True)
hname = serializers.CharField(label='人物', max_length=20)
hcomment = serializers.CharField(label='评论量', max_length=200, required=False)
hgender = serializers.ChoiceField(choices=GENDER_CHOICES, default=1)
# 关联属性
# hbook = **** 下面单独说明关联属性的定义方法
2. 进行序列化操作
1.查询对象
2.构造序列化器的对象 # 如果查询结果包含多个对象,必须指定many=True
3.调用序列化器的对象属性 data 获取序列化后的字典.
"""单一对象的序列化""" # 结果是一个字典
def book(request):
book1 = BookInfo.objects.get(pk=1) # 查询对象
book_serializer = BookInfoSerializer(book1) # 构造序列化器对象
book_dict = book_serializer.data # 实现序列化操作
print(book_dict)
# {'bpub_date': '1980-05-01', 'id': 1, 'btitle': '射雕英雄传'} # rest_framework中定义的一个字典类型
print(type(book_dict))
#
"""多个对象的序列化""" # OrderedDict列表
def hero(request):
hlist = HeroInfo.objects.filter(hbook_id=1) # 查询对象
hero_serializer = HeroInfoSerializer(hlist, many=True) # 同时返回多个对象必须说明,否则报错
hlist2 = hero_serializer.data # 实现序列化操作
print(hlist2) # rest_framework中定义的一种列表
# [OrderedDict([('id', 1), ('hname', '郭靖'), ('hcomment', '降龙十八掌'), ('hgender', 1), ('hbook_id', 1)]),
# OrderedDict([('id', 2), ('hname', ('hcomment', '打狗棍法'), ('hgender', 0), ('hbook_id', 1)]),
# OrderedDict([('id', 3), ('hname', '黄药师'), ('hcomment', '弹指神通'), ('hge('hbook_id', 1)]),
# OrderedDict([('id', 4), ('hname', '欧阳锋'), ('hcomment', '蛤蟆功'), ('hgender', 1), ('hbook_id', 1)]),
# OrderedDict([('i, ('hname', '梅超风'),('hcomment', '九阴白骨爪'), ('hgender', 0), ('hbook_id', 1)])]
print(type(hlist2)
# < class 'rest_framework.utils.serializer_helpers.ReturnList'>
三.关联属性的序列化
# 注意: 指定 read_only=True 不然容易报错
1.以主键形式输出
hbook = serializers.PrimaryKeyRelatedField(read_only=True)
# {'id': 1, 'hbook': 1, 'hgender': 1, 'hcomment': '降龙十八掌', 'hname': '郭靖', 'hbook_id': 1}"""
2.以字符串的形式输出
hbook = serializers.StringRelatedField(read_only=True)
# {'hcomment': '降龙十八掌', 'id': 1, 'hbook_id': 1, 'hname': '郭靖', 'hbook': '射雕英雄传', 'hgender': 1}
3.以超链接的形式输出
需要在项目配置的urls.py和应用的urls.py文件中设置namespace和name,并为序列化器对象传递request参数(即:context={'request': request})
hbook = serializers.HyperlinkedRelatedField(read_only=True, view_name='booktest:book1')
# {'hname': '郭靖', 'id': 1, 'hgender': 1, 'hbook': 'http://127.0.0.1:8000/drf/book/1', 'hcomment': '降龙十八掌',
# 'hbook_id': 1}
4.指定对象的某个属性输出
hbook = serializers.SlugRelatedField(read_only=True, slug_field='bpub_date')
# {'id': 1, 'hname': '郭靖', 'hbook': datetime.date(1980, 5, 1), 'hgender': 1, 'hcomment': '降龙十八掌', 'hbook_id': 1}
5.指定关联对象的序列化噐输出
hbook = BookInfoSerializer()
# {'hbook_id': 1, 'hbook': OrderedDict([('id', 1), ('btitle', '射雕英雄传'), ('bpub_date', '1980-05-01')]),
# 'hname': '郭靖', 'hgender': 1, 'id': 1, 'hcomment': '降龙十八掌'}
6.自定义输出方案
需要自定义序列化器类,继承自serializers.Serializer, 再重写 to_representation(self, value)方法.
class BookRelatatedField(serializers.RelatedField):
def to_representation(self, value):
""" value: 表示对应的属性"""
return '%d-%s' % (value.id, value.btitle)
hbook = BookRelatatedField(read_only=True)
# 如果关联属性包含多个对象,必须指定 many=True.heroinfo的输出类似.