如果想为Django存在的模型类快速创建序列化器,可以使用DRF框架封装好的ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类
- 基于模型类的字段条件创建约束
- 内部已经封装了create与update方法,序列化器对象在调用save()方法时,会自动对数据库进行操作
指定全字段
# 继承自serializers.ModelSerializer
class StudentInfoSerializer(serializers.ModelSerializer)
class Meta:
model = StudentInfo # 指定要依据的模型类
fields = '__all__' # 设置全部字段自动生成
自定义过滤字段
- 使用
fields
来明确字段, 可以写明具体哪些字段
# 继承自serializers.ModelSerializer
class StudentInfoSerializer(serializers.ModelSerializer)
class Meta:
model = StudentInfo # 指定要依据的模型类
fields = ['id', 'name'] # 列表中设置指定要生成的字段
- 使用
exclude
可以明确排除掉哪些字段
# 继承自serializers.ModelSerializer
class StudentInfoSerializer(serializers.ModelSerializer):
class Meta:
model = StudentInfo # 指定要依据的模型类
exclude = ['info'] # 指定哪些字段不需要自动生成
- 通过
read_only_fields
指明只读字段,即仅用于序列化输出的字段
# 继承自serializers.ModelSerializer
class StudentInfoSerializer(serializers.ModelSerializer):
class Meta:
model = StudentInfo # 指定要依据的模型类
fields = '__all__' # 自定生成全部字段
read_only_fields = ['id', 'name'] # 指定列表中的字段仅用于序列化操作
-
extra_kwargs
参数为ModelSerializer添加或修改原有的选项参数
# 继承自serializers.ModelSerializer
class StudentInfoSerializer(serializers.ModelSerializer):
class Meta:
model = StudentInfo # 指定要依据的模型类
fields = '__all__' # 设置全部字段自动生成
extra_kwargs = {
name: { # 给name字段设置额外的约束
'min_value': 0, # 设置最小的长度
'required': True # 设置是否必传
}
info: { # 同上
'min_value': 0,
'required': True
}
}
外键
# 班级模型类
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 StudentInfo(models.Model):
name = models.CharField(max_length=20, verbose_name='姓名')
clsinfo = models.ForeignKey(ClassInfo, related_name='cls_stu)
class Meta:
db_table = 'student'
def __str__(self):
return self.name
那么在
Django REST framework
我们通常按下面的方式定义Serialize
r 类. 在ClassInfo
类中增加一个属性cls_stu
(studen
t外键到class
的别名) 来保存当前class
对象所有的学生集合. 但是此时有个问题如果此Class
对象所拥有的Student
比较多, 此时就会影响性能. 比如:
# 班级序列化器
class ClassSerializer(serializers.ModelSerializer):
cls_stu = serializers.PrimaryKeyRelatedField(many=True, required=False, read_only=True)
class Meta:
model = Article
fields = ('id', 'name', 'info', 'cls_stu')
# 学生序列化器
class StudentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ('id', 'name', 'clsinfo')
-
但是这样会出现一个问题: 这样序列化
Class
对象的时候会把 所有与Clas
对象关联的student
对象的也序列化起来,就算是我们用IntegerField
或者StringRelatedField
那也会序列化很多用户的信息 -
其实在很多时候我们并不需要在查询
Class
对象的时候查询所拥有的Student
对象,很多时候我们只是需要一个Class
所拥有Student
对象的总数就可以了,如果有需要再去查询Student
列表详细。此时我们就可以使用Django REST framework
提供的SerializerMethodField
来实现这个目的
# 班级序列化器
class ClassSerializer(serializers.ModelSerializer):
get_cls_stu_count = serializers.SerializerMethodField()
class Meta:
model = Article
fields = ('id', 'name', 'info', 'get_cls_stu_count')
def get_cls_stu_count(self, obj):
return obj.cls_stu.all().count()
# 学生序列化器
class StudentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ('id', 'name', 'clsinfo')
- 首先在
ClassSerializer
中去除cls_stu
属性 - 然后在
ClassSerializer
中增加一个属性get_cls_stu_count
, 并把这个属性添加到Meta
的fields
列表里 - 添加一个
get_cls_stucount
方法,这个方法的命名规则就是在上面声明的属性前面加上个'get'
前缀,并接受一个obj
参数,这个obj
参数就是当前的ClassInfo
对象实例。
网友评论