欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

DRF-Serializer序列化

程序员文章站 2022-07-12 11:20:42
...

1. 基本查询

测试用例

# Django ORM
class StudentInfo(models.Model):
    name = models.CharField(max_length=20, verbose_name='姓名')
    birthday = models.DateField(verbose_name='生日', null=True)
    money = models.IntegerField(default=0, verbose_name='现金')
    image = models.ImageField(upload_to='studenttest', verbose_name='照片', null=True)

# 序列化器用例
from rest_framework import serializers

class StudentSerializer(serializers.Serializer)
    id = serializers.IntegerField(label='ID', read_only=True)
    name = serializers.CharField(label='姓名', max_length=20)
    birthday = serializers.DateField(label='生日', required=False)
    money = serializers.IntegerField(label='现金', required=False)
    image = serializers.ImageField(label='照片', required=False)
  • 单一对象查询
# 得到一个学生对象
student = StudentInfo.objects.get(id=2)

# 构造序列化器对象
serializer = StudentSerializer(student)

# 获得序列化后的数据
print(serializer.data)
# {'id': 2, 'name': '小明', 'birthday': '1996-07-24', 'money': 36,  'image': None}

序列化器对象通过data属性可以获取序列化后的数据

  • 查询集QuerySet查询
# 得到所有的学生
students = StudentInfo.objects.all()

# 构造序列化器对象
serializers = StudentSerializer(students, many = True)

# 打印输出结果
print(serializers.data)
# [OrderedDict([('id', 1), ('name', '小花'), ('birthday', '1998-03-22'), ('money', 21), ('image', None]), OrderedDict([('id', 2), ('name', '小明'), ('birthday', '1996-07-24'), ('money', 36), ('image', None])]

如果要被序列化的是包含多条数据的查询集QuerySet,可以通过添加many=True参数补充说明

2. 关联外键嵌套查询

如果需要序列化的数据中包含有其他关联对象,则对关联对象数据的序列化需要指明

  • 比如:一个学生有外键对应的班级,那这个字段该如何显示?

测试用例

from rest_framework import serializers

# 班级类用例
class ClassInfo(models.Model):
    name = models.CharField(max_length=20, verbose_name='班级名称')
    Info = models.CharField(max_length=20, verbose_name='班级信息')

    class Meta:
        db_table = 'class'
    def __str__(self):
        return self.name

# 班级类序列化器用例
class ClassInfoSerializer(serializers.Serializer)
    name = serializers.CharField(label='班级名称', max_length=20)
    Info = serializers.CharField(label='班级信息', max_length=20)


# 学生类用例
class StudentInfo(models.Model):
    name = models.CharField(max_length=20, verbose_name='姓名')
    birthday = models.DateField(verbose_name='生日', null=True)
    money = models.IntegerField(default=0, verbose_name='现金')
    image = models.ImageField(upload_to='studenttest', verbose_name='照片', null=True)
    class Meta:
        db_table = 'students'
    def __str__(self):
        return self.name

# 学生类序列化器用例
class StudentSerializer(serializers.Serializer)
    id = serializers.IntegerField(label='ID', read_only=True)
    name = serializers.CharField(label='姓名', max_length=20)
    birthday = serializers.DateField(label='生日', required=False)
    money = serializers.IntegerField(label='现金', required=False)
    image = serializers.ImageField(label='照片', required=False)
    #定义外键字段
    hclass = serializers.PrimaryKeyRelatedField(label='班级', read_only=True)
    #hclass = serializers.StringRelatedField(label='班级', read_only=True)
    #hclass = ClassInfoSerializer(label='班级', read_only=True)
  • 1. PrimaryKeyRelatedField: 此字段将被序列化为关联对象的主键
student = StudentInfo.objects.get(id=2)
serializer = StudentSerializer(student)
print(serializer.data)
# {'id': 2, 'name': '小明', 'birthday': '1996-07-24', 'money': 36,  'image': None, 'hclass':2}
  • 2. StringRelatedField: 此字段将被序列化为关联对象的字符串表示方式(即模型类中__str__方法的返回值)
student = StudentInfo.objects.get(id=2)
serializer = StudentSerializer(student)
print(serializer.data)
# {'id': 2, 'name': '小明', 'birthday': '1996-07-24', 'money': 36,  'image': None, 'hclass':'九年级二班'}
  • 3. 使用关联对象的序列化器
student = StudentInfo.objects.get(id=2)

# 使用了自定义的序列化器
serializer = StudentSerializer(student)
print(serializer.data)
# {'id': 2, 'name': '小明', 'birthday': '1996-07-24', 'money': 36,  'image': None, 'hclass':OrderedDict([('id', 2), ('name', '九年级二班'), ('Info', '这里是九年级二班的信息')])}

many参数

如果关联的对象不止一个,比如一个班级会有多个学生,此时关联字段类型的指明仍可使用上述三种方式,只是在声明关联字段时,多补充一个many=True参数即可

# 班级类用例
class ClassInfoSerializer(serializers.Serializer)
    name = serializers.CharField(label='班级名称', max_length=20)
    Info = serializers.CharField(label='班级信息', max_length=20)
    studentinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)  # 新增

serializer = ClassInfoSerializer(ClassInfo.objects.get(id=2))
print(serializer.data)
# {'id': 2, 'name': '九年级二班', 'info': 'xxxxxx', 'studentinfo_set': [1, 2, 9]} #1, 2, 9代表了字表中与之关联的学生id