DRF中序列化器的序列化操作

                                                             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的输出类似.

你可能感兴趣的:(DRF)