前言
我们上篇文章使用到了Serializer
类,可能有小伙伴说太过复杂,那么本篇就为大家带来更加简便的序列化类ModelSerializer
ModelSerializer
先来看下ModelSerializer
的代码结构如下:
可以看到ModelSerializer
是继承自Serializer
,官方是这么介绍到的
ModelSerializer
只是一个常规的Serializer
,只是做了以下事情
- 将自动填充一组默认字段
- 将自动填充一组默认验证程序
- 提供了默认的
.create()
和.update()
实现
我们将之前的Serializer
类现在用ModelSerializer
来实现
class StudentModelSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = ['id', 'name', 'age', 'sex']
默认情况下,所有的模型的字段都将映射到序列化器上相应的字段。
如果你希望在模型序列化器中使用默认字段的一部分,你可以使用fields
或exclude
选项来执行此操作
- fields:需要哪些模型字段
- exclude:排除哪些模型字段
官方强烈建议你使用fields
属性显式的设置要序列化的字段。这样就不太可能因为你修改了模型而无意中暴露了数据。
如果我们需要使用模型的全部字段,则可以将fields
属性设置成'__all__'
默认情况下,fields
里的字段既参加序列化也参加反序列化,如果我们想某个字段只序列化或反序列化可以定义extra_kwargs
字段,代码如下:
class StudentModelSerializer(serializers.ModelSerializer):
# classes = ClassesModelSerializer(read_only=True)
class Meta:
model = Student
fields = ['id', 'name', 'age', 'sex', 'password']
extra_kwargs = {
"password": {
"write_only": True
},
"id": {
"read_only": False
}
}
上面代码如果不写extra_kwargs
,那么password
默认参加序列化和反序列化,那么密码就会返回给前端了,这里我们定义了extra_kwargs
字段,在字段中设置了password
只能反序列化,那么用户只能提交密码,而后台不会返回密码给前台
当然,extra_kwargs
也可以自定义错误信息,如果业务有需要,可以查看官方文档
指定嵌套序列化
上面我们都是单模型的序列化,但是实际业务中我们不会这么简单,一定会遇到关系模型的序列化,下面我们来讲解关系模型的序列化
首先我们看一下models
模型内容:
class Classes(models.Model):
name = models.CharField(max_length=20, verbose_name="班级名")
class Meta:
db_table = "classes"
class Student(models.Model):
SEX_CHOICES = (
(1,'男'),
(2, '女')
)
name = models.CharField(max_length=20, verbose_name='姓名')
age = models.IntegerField(null=True, blank=True, verbose_name='年龄')
sex = models.IntegerField(choices=SEX_CHOICES, default=1, verbose_name='性别')
classes = models.ForeignKey(Classes, on_delete=models.SET_NULL, verbose_name="班级", null=True, related_name='students')
class Meta:
db_table = "student"
我们定义了Student
学生类,里面定义了一个外键classes
关联Classes
,一个班级中可以有多个学生,而一个学生只能属于一个班级,典型的一对多的关系,接下来我们看序列化函数
class ClassesModelSerializer(serializers.ModelSerializer):
class Meta:
model = Classes
fields = ['id', 'name', 'students']
class StudentModelSerializer(serializers.ModelSerializer):
classes = ClassesModelSerializer(read_only=True)
class Meta:
model = Student
fields = ['id', 'name', 'age', 'sex', 'classes']
我们在StudentModelSerializer
中增加了一个额外的字段classes
,并将字段设置为只读,一般外键只做序列化,并且在fields
列表中添加了该字段。
注意:我们在创建外键模型时,必须在外键中设置related_name
,如果没设置,序列化时不会返回关联的外键内容
接下来我们访问http://127.0.0.1:8000/drf/student/
,会看到返回的学生表中包含了班级表的内容,如下
{
"id": 1,
"name": "jkc",
"age": 18,
"sex": 1,
"classes": {
"id": 1,
"name": "班级1",
"students": [
1,
15,
18
]
}
},