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

DRF-serializers.ModelSerializer模型类序列化器

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

如果想为Django存在的模型类快速创建序列化器,可以使用DRF框架封装好的ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类

  • 基于模型类的字段条件创建约束
  • 自动生成序列化器(serializer)
  • 内部已经封装了createupdate方法,序列化器对象在调用save()方法时,会自动对数据库进行操作

1. 基础定义

# 继承自serializers.ModelSerializer
class StudentInfoSerializer(serializers.ModelSerializer)
    class Meta:
        model = StudentInfo # 指定要依据的模型类
        fields = '__all__' # 设置全部字段自动生成

2. 自定义过滤字段

  • 使用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__' # 自定生成全部字段
		ead_only_fields = ['id', 'name'] # 指定列表中的字段仅用于序列化操作

3. 添加额外约束

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
			}
		}

4. 使用SerializerMethodField 优化

  • 测试用例
# 班级模型类
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 我们通常按下面的方式定义 Serializer 类. 在 ClassInfo 类中增加一个属性 cls_stu(student外键到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 对象的时候会把 所有与 Class 对象关联的 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')
  1. 首先在 ClassSerializer 中去除 cls_stu 属性
  2. 然后在 ClassSerializer 中增加一个属性 get_cls_stu_count, 并把这个属性添加到 Meta 的 fields 列表里
  3. 添加一个 get_cls_stu_count 方法,这个方法的命名规则就是在上面声明的属性前面加上个 ‘get_’ 前缀,并接受一个 obj 参数,这个 obj 参数就是当前的 ClassInfo 对象实例。
相关标签: python django