REST framework入坑(3)-序列化
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