一 序列化器的作用
- 1. 序列化,序列化器会把模型对象转换成字典,经过视图中response对象以后变成json字符串
- 2. 反序列化,视图中request会把客户端发送过来的数据转换成字典,序列化器可以把字典转成模型
- 3. 反序列化,把客户端发送过来的数据进行校验,并存储入库
二 定义序列化器
Django REST framework中的Serializer使用类来定义,必须直接或间接继承于rest_framework.serializers.Serializer。
我们已有了一个数据库模型类stuapi/Student,我们想为这个Student模型类提供一个序列化器类,可以定义如下,sers/serializers.py,代码:

from rest_framework import serializers """ rest_framework.serializers 是drf提供给开发者调用的序列化器模块 里面声明了所有的可用序列化器的基类,常用的有: Serializer 序列化器基类,drf中所有的序列化器类都必须继承于 Serializer ModelSerializer 模型序列化器基类,是序列化器基类Serializer的子类,在工作中,除了Serializer基类以外,最常用的序列化器类基类 """ class StudentSerializer(serializers.Serializer): """学生信息序列化器""" # 1. 转换的字段声明 id = serializers.IntegerField() name = serializers.CharField() sex = serializers.BooleanField() age = serializers.IntegerField() description = serializers.CharField() # 2. 如果当前序列化器继承的是ModelSerializer,则需要声明调用的模型信息 # class Meta: # model = 模型 # fields = "__all__" # fields = ["字段1","字段2",....] # 3. 验证代码的对象方法 # def validate(self, attrs): # 方法名validate是固定的,attrs就是客户端发送的数据,字典格式 # pass # return attrs # def validate_<字段名>(self, data): # 方法名的格式必须以 validate_<字段名> 为名称,否则序列化器不识别! # pass # return data # 4. 模型操作的扩展方法 # def create(self, validated_data): # 添加数据操作,添加数据以后,就自动实现了从字典变成模型对象的过程 # pass # # def update(self, instance, validated_data): # 更新数据操作,更新数据以后,就自动实现了从字典变成模型对象的过程 # pass
⚠️ serializer不是只能为数据库模型类转换数据格式,也可以为非数据库模型类的转换数据格式。serializer是独立于数据库之外的存在。
serailziers中的字段声明时提供给客户端的,所以常用字段类型:
序列化器 字段 | 模型 字段 | 序列化器字段选项 |
---|---|---|
BooleanField | BooleanField | BooleanField() |
CharField | CharField TextField等 | CharField( max_length=最大长度, min_length=最小长度, allow_blank=False, 表示是否允许客户端提交空字符串,False表示不允许 trim_whitespace=True,表示是否移除字符串两边的空白字符,True表示移除 ) |
EmailField | EmailField | EmailField(max_length=None, min_length=None, allow_blank=False) |
RegexField | CharField | RegexField(regex=正则表达式, max_length=None, min_length=None, allow_blank=False) |
SlugField | SlugField | SlugField(max_length=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9*-]+ |
URLField | URLField | URLField(max_length=200, min_length=None, allow_blank=False) |
UUIDField | UUIDField | UUIDField(format='hex_verbose') format: 设置UUID格式,一般默认使用hex_verbose 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a" 'int' - 如: "123456789012312313134124512351145145114" 'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a" |
IPAddressField | IPAddressField | IPAddressField(protocol='both', unpack_ipv4=False, **options) |
IntegerField | SmallIntegerFiled IntegerField BigIntegerField | IntegerField(max_value=最大值, min_value=最小值) |
FloatField | FloatField | FloatField(max_value=None, min_value=None) |
DecimalField | DecimalField | DecimalField( max_digits=数值的数字总个数, decimal_places=小数位个数, coerce_to_string=None, max_value=None, min_value=None) |
DateTimeField | DateTimeField | DateTimeField( format=api_settings.DATETIME_FORMAT, 表示日期格式 input_formats=None) |
DateField | DateField | DateField(format=api_settings.DATE_FORMAT, input_formats=None) |
TimeField | TimeField | TimeField(format=api_settings.TIME_FORMAT, input_formats=None) |
DurationField | DurationField | DurationField() |
ChoiceField | 对应整型或字符串中的choices=属性选项 | ChoiceField(choices=元祖选项) choices与Django的用法相同 |
MultipleChoiceField | 对应整型或字符串中的choices=属性选项 | MultipleChoiceField(choices=元祖选项) choices与Django的用法相同 |
FileField | FileField | FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
ImageField | ImageField | ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
ListField | python里面的List | ListField(child=模型列表, min_length=None, max_length=None) |
DictField | python里面的Dict | DictField(child=模型对象) |
字段的选项参数:
参数名称 | 作用 |
---|---|
max_length | 最大长度 |
min_lenght | 最小长度 |
allow_blank | 是否允许为空字符串 |
trim_whitespace | 是否移除两边的空白字符 |
max_value | 最小数值 |
min_value | 最大数值 |
字段的通用选项参数:
参数名称 | 说明 |
---|---|
read_only | 表明该字段仅用于序列化输出,默认False |
write_only | 表明该字段仅用于反序列化输入,默认False |
required | 表明该字段在反序列化时必须输入,默认True |
default | 反序列化时使用的默认值 |
miss | 序列化时使用的默认值 |
allow_null | 表明反序列化时该字段是否允许传入None,默认False |
validators | 表明反序列化时该字段使用的验证器函数 |
error_messages | 表明反序列化时如果验证出错了,返回错误错误信息的字典 |
label | 用于HTML展示API页面时,显示的字段名称。 如果不写,则默认采用模型的verbose_name,但是前提是当前序列化器继承ModelSerializer |
help_text | 用于HTML展示API页面时,显示的字段帮助提示信息 如果不写,则默认采用模型的help_text,但是前提是当前序列化器继承ModelSerializer |
三 创建Serializer对象
定义好Serializer类后,就可以创建Serializer对象了。Serializer的构造方法为:
序列化器(instance=None, data=empty, many=False, context=None, **kwargs) # 说明: 1)序列化器用于序列化时,则需要将模型类对象传入instance参数 2)序列化器用于反序列化时,将要被反序列化的数据传入data参数 3)序列化器用于序列化时,当instance的值是一个QuerySet类型,则需要声明many=True 4)除了以上参数外,在构造Serializer对象时,还可通过context参数额外添加数据传入到序列化器中。
常见的写法:
serializer = Student1Serializer(instance=student) # 序列化单个模型对象为dict字典 serializer = Student1Serializer(instance=student_list, many=True) # 序列化多个模型对象为list列表 serializer = Student1Serializer(instance=student_list, context={'request': request}) # 如果传递数据到序列化器中,可以使用context # 说明 通过context参数附加的数据,可以通过Serializer对象的context属性获取。 1. 使用序列化器的时候一定要注意,序列化器声明了以后,不会自动执行,需要我们在视图中进行调用才可以。 2. 序列化器无法直接接收数据,需要我们在视图中实例化序列化器对象时把使用的数据通过instance传递过来。 3. 序列化器的字段声明类似于我们前面使用过的模型。 4. 开发restful api时,序列化器会帮我们把模型对象转换成字典
四 序列化器的使用
序列化器的使用分两个阶段:
-
在客户端请求时,使用序列化器可以完成对数据的反序列化。
-
在服务器响应时,使用序列化器可以完成对数据的序列化。
一 序列化
一 基本使用

from django.views import View from .serializers import StudentSerializer from stuapi.models import Student from django.http.response import JsonResponse # Create your views here. class Student1View(View): def get1(self, request): """序列化器的基本使用:序列化单个模型对象为字典""" student = Student.objects.first() print(student) # 把模型对象作为instance参数的值传递到序列化器中进行转换数据格式 serializer = StudentSerializer(instance=student) print(serializer.data) """ {'id': 1, 'name': 'xiaoming', 'sex': True, 'age': 16, 'description': 'xxxxx'} """ return JsonResponse(serializer.data) """如果要被序列化的是包含多条数据的查询集QuerySet,可以通过添加**many=True**参数补充说明""" def get(self, request): """序列化器的基本使用:序列化多个模型对象为列表""" student_list = Student.objects.all() print(student_list) # 把模型列表作为instance参数传递到序列化器中进行数据格式转换 serializer = StudentSerializer(student_list, many=True) print(serializer.data) return JsonResponse(serializer.data, safe=False)
二 反序列化
一 数据验证
使用序列化器进行反序列化时需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象。在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False。
验证失败,可以通过序列化器对象的errors属性获取错误信息,返回字典,包含了字段和字段的错误。如果是非字段错误,可以通过修改REST framework配置中的NON_FIELD_ERRORS_KEY来控制错误字典中的键名。
验证成功,可以通过序列化器对象的validated_data属性获取数据。
1 定义字段类型和选项参数验证
在定义序列化器时,指明每个字段的序列化类型和选项参数,本身就是一种验证行为。

from rest_framework import serializers """ rest_framework.serializers 是drf提供给开发者调用的序列化器模块 里面声明了所有的可用序列化器的基类,常用的有: Serializer 序列化器基类,drf中所有的序列化器类都必须继承于 Serializer ModelSerializer 模型序列化器基类,是序列化器基类Serializer的子类,在工作中,除了Serializer基类以外,最常用的序列化器类基类 """ class StudentSerializer(serializers.Serializer): """学生信息序列化器""" # 1. 转换的字段声明 id = serializers.IntegerField(read_only=True) # 在序列化阶段使用,在反序列化阶段中被忽视掉 name = serializers.CharField(max_length=12, min_length=4, error_messages={ # 字段选项在反序列化阶段中校验字段如果失败的错误提示 # "选项名": "提示内容", "min_length": "name字段的值必须至少{min_length}个字符", "max_length": "name字段的值必须低于{max_length}个字符", "required": "name字段是必填字段", }) age = serializers.IntegerField(min_value=1, max_value=100, error_messages={ "min_value": "年龄太小了,必须大于或等于{min_value}", "max_value": "年龄太大了,必须小于或等于{max_value}", }) sex = serializers.BooleanField(default=True) # default=True 等价于设置当前字段为选填字段,默认值为True description = serializers.CharField() password = serializers.CharField() # 用户密码 re_password = serializers.CharField() # 确认密码 # 2. 如果当前序列化器继承的是ModelSerializer,则需要声明调用的模型信息 # class Meta: # model = 模型 # fields = "__all__" # fields = ["字段1","字段2",....] # 3. 验证代码的对象方法 # def validate(self, attrs): # 方法名validate是固定的,attrs就是客户端发送的数据,字典格式 # pass # return attrs # def validate_<字段名>(self, data): # 方法名的格式必须以 validate_<字段名> 为名称,否则序列化器不识别! # pass # return data # 4. 模型操作的扩展方法 # def create(self, validated_data): # 添加数据操作,添加数据以后,就自动实现了从字典变成模型对象的过程 # pass # # def update(self, instance, validated_data): # 更新数据操作,更新数据以后,就自动实现了从字典变成模型对象的过程 # pass

from django.views import View from .serializers import StudentSerializer from stuapi.models import Student from django.http.response import JsonResponse # Create your views here. class Student1View(View): def get1(self, request): """序列化器的基本使用:序列化单个模型对象为字典""" student = Student.objects.first() print(student) # 把模型对象作为instance参数的值传递到序列化器中进行转换数据格式 serializer = StudentSerializer(instance=student) print(serializer.data) """ {'id': 1, 'name': 'xiaoming', 'sex': True, 'age': 16, 'description': 'xxxxx'} """ return JsonResponse(serializer.data) def get2(self, request): """序列化器的基本使用:序列化多个模型对象为列表""" student_list = Student.objects.all() print(student_list) # 把模型列表作为instance参数传递到序列化器中进行数据格式转换 serializer = StudentSerializer(student_list, many=True) print(serializer.data) return JsonResponse(serializer.data, safe=False) def get(self, request): """序列化器的基本使用:反序列化验证数据""" # 模拟客户端提交过来的数据 data = { # "name": "root", "name": "xiaoming", "age": 20, "classmate": 303, "description": "hello world", "password": "123", "re_password": "123", } # 实例化序列化器用于反序列化 serializer = StudentSerializer(data=data) # # 验证失败不会抛出异常 # ret = serializer.is_valid() # if ret: # print("验证通过!") # print(serializer.validated_data) # 获取验证通过后的客户端提交的数据 # else: # print("验证失败!获取验证错误的提示信息") # print(serializer.errors) # print(serializer.error_messages) # 验证失败则会抛出异常[最常用] serializer.is_valid(raise_exception=True) print("验证通过,验证结果数据:", serializer.validated_data) return JsonResponse("ok", safe=False)
如果需要再补充定义验证行为,可以使用以下三种方法:
2 validate_字段名
校验指定字段数据的方法,serializers.py,代码
"""校验指定字段数据的方法""" def validate_name(self, data): # 方法名的格式必须以 validate_<字段名> 为名称,否则序列化器不识别! if data == "root": raise serializers.ValidationError(detail=f"name字段的值不能是{data}", code="validate") print("一旦出现异常,序列化器将返回异常给调用处,不会继续往下执行") return data
视图代码,测试
def get(self, request): """序列化器的基本使用:反序列化验证数据""" # 模拟客户端提交过来的数据 data = { # "name": "root", "name": "xiaoming", "age": 20, "classmate": 303, "description": "hello world", "password": "123", "re_password": "123", } # 实例化序列化器用于反序列化 serializer = StudentSerializer(data=data) # 验证失败则会抛出异常[最常用] serializer.is_valid(raise_exception=True) print("验证通过,验证结果数据:", serializer.validated_data) return JsonResponse("ok", safe=False)
3 validate
在序列化器中需要同时对多个字段进行比较验证时,可以定义validate方法来验证,如serializers.py,代码
"""同时校验多个字段的方法""" def validate(self, attrs): # 方法名validate是固定的,attrs就是客户端发送的数据,字典格式 if attrs["password"] != attrs["re_password"]: raise serializers.ValidationError(detail="对不起,密码与确认密码不一致!请重新填写", code="validate") return attrs
视图代码,测试,同上
4 validators选项
在字段声明中添加validators选项参数,也可以补充验证行为函数,如serializers.py,代码

from rest_framework import serializers """ rest_framework.serializers 是drf提供给开发者调用的序列化器模块 里面声明了所有的可用序列化器的基类,常用的有: Serializer 序列化器基类,drf中所有的序列化器类都必须继承于 Serializer ModelSerializer 模型序列化器基类,是序列化器基类Serializer的子类,在工作中,除了Serializer基类以外,最常用的序列化器类基类 """ def check_desc(data): """ 验证函数,通过字段声明的validators选项中作为列表成员传递使用 data: 当前要校验的字段的值 """ if "hi" in data: raise serializers.ValidationError(detail="个性签名中不能出现废话!", code="validators") # 验证代码的最后,必须把本地校验的数据作为返回值返回给外界,否则serializer序列化器对象会丢失验证的数据 return data class StudentSerializer(serializers.Serializer): """学生信息序列化器""" # 1. 转换的字段声明 id = serializers.IntegerField(read_only=True) # 在序列化阶段使用,在反序列化阶段中被忽视掉 name = serializers.CharField(max_length=12, min_length=4, error_messages={ # 字段选项在反序列化阶段中校验字段如果失败的错误提示 # "选项名": "提示内容", "min_length": "name字段的值必须至少{min_length}个字符", "max_length": "name字段的值必须低于{max_length}个字符", "required": "name字段是必填字段", }) age = serializers.IntegerField(min_value=1, max_value=100, error_messages={ "min_value": "年龄太小了,必须大于或等于{min_value}", "max_value": "年龄太大了,必须小于或等于{max_value}", }) sex = serializers.BooleanField(default=True) # default=True 等价于设置当前字段为选填字段,默认值为True description = serializers.CharField(validators=[check_desc]) # validators=[验证函数名, 验证函数名....] password = serializers.CharField() # 用户密码 re_password = serializers.CharField() # 确认密码 # 2. 如果当前序列化器继承的是ModelSerializer,则需要声明调用的模型信息 # class Meta: # model = 模型 # fields = "__all__" # fields = ["字段1","字段2",....] # 3. 验证代码的对象方法 """同时校验多个字段的方法""" def validate(self, attrs): # 方法名validate是固定的,attrs就是客户端发送的数据,字典格式 if attrs["password"] != attrs["re_password"]: raise serializers.ValidationError(detail="对不起,密码与确认密码不一致!请重新填写", code="validate") # 验证代码的最后,必须把本地校验的数据作为返回值返回给外界,否则serializer序列化器对象会丢失验证的数据 # 返回的验证数据如果被修改了,则会覆盖客户端提交的数据 # attrs["description"] = "hello!!!!" return attrs """校验指定字段数据的方法""" def validate_name(self, data): # 方法名的格式必须以 validate_<字段名> 为名称,否则序列化器不识别! if data == "root": raise serializers.ValidationError(detail=f"name字段的值不能是{data}", code="validate") print("一旦出现异常,序列化器将返回异常给调用处,不会继续往下执行") # 验证代码的最后,必须把本地校验的数据作为返回值返回给外界,否则serializer序列化器对象会丢失验证的数据 return data # 4. 模型操作的扩展方法 # def create(self, validated_data): # 添加数据操作,添加数据以后,就自动实现了从字典变成模型对象的过程 # pass # # def update(self, instance, validated_data): # 更新数据操作,更新数据以后,就自动实现了从字典变成模型对象的过程 # pass
视图代码,测试,同上
二 保存数据
前面的验证数据成功后,我们可以使用序列化器来完成数据反序列化的过程.这个过程可以把数据转成模型类对象。可以通过实现create()和update()两个方法来实现。serializers.py,代码
# 4. 模型操作的扩展方法 def create(self, validated_data): # 添加数据操作,添加数据以后,就自动实现了从字典变成模型对象的过程 """ 添加操作 validated_data:经过验证后的客户端数据 """ student = Student.objects.create( name=validated_data.get("name"), age=validated_data.get("age"), sex=validated_data.get("sex"), classmate=validated_data.get("classmate"), description=validated_data.get("description") ) # 注意,可以把新增的模型对象作为返回值返给serializer.save() return student def update(self, instance, validated_data): # 更新数据操作,更新数据以后,就自动实现了从字典变成模型对象的过程 """更新数据""" if validated_data.get('name'): instance.name = validated_data.get('name') if validated_data.get('age'): instance.age = validated_data.get('age') if validated_data.get('sex') is not None: instance.sex = validated_data.get('sex') if validated_data.get('classmate'): instance.classmate = validated_data.get('classmate') if validated_data.get('description'): instance.description = validated_data.get('description') instance.save() return instance
实现了上述两个方法后,在反序列化数据的时候,就可以通过序列化器的save()方法自动调用
serializer.save()
如果创建序列化器对象时没有传递instance参数,则调用序列化器内部的create()方法,相反,创建序列化器对象时传递了instance参数,则调用序列化器内部的update()方法。
视图代码,测试
def get4(self, request): """序列化器的基本使用:自动调用create添加数据""" # 模拟客户端提交过来的数据 data = { "name": "xiaoming", "age": 20, "classmate": 303, "description": "hello world", "password": "456", "re_password": "456", } serializer = StudentSerializer(data=data) serializer.is_valid(raise_exception=True) serializer.save() # save源代码中,根据实例化序列化器时是否传递了instance, # 如果传递了instance参数,则serializer.save()会自动调用序列化器内部的update,并把instance与验证后的validated_data作为参数 # 如果没有传递instance参数,则serializer.save()会自动调用序列化器内部的create方法,并把验证后的validated_data作为参数 # 使用serializer.data实现序列化操作 return JsonResponse(serializer.data, status=201, safe=False) def get(self, request): """序列化器的基本使用:自动调用update修改数据""" # 模拟客户端提交过来的数据 data = { "name": "小明同学", "age": 20, "classmate": 305, "description": "hello world", "password": "456", "re_password": "456", } # 查询数据库,得到要修改的模型对象 student = Student.objects.get(pk=9) serializer = StudentSerializer(instance=student, data=data) serializer.is_valid(raise_exception=True) serializer.save() # save源代码中,根据实例化序列化器时是否传递了instance, # 如果传递了instance参数,则serializer.save()会自动调用序列化器内部的update,并把instance与验证后的validated_data作为参数 # 如果没有传递instance参数,则serializer.save()会自动调用序列化器内部的create方法,并把验证后的validated_data作为参数 # 使用serializer.data实现序列化操作 return JsonResponse(serializer.data, status=201, safe=False)
三 附加说明
1) 在对序列化器进行save()保存数据时,可以给序列化器的save方法额外传递数据,这些数据可以在create()和update()中的validated_data参数获取到,用于补充数据给模型的
serializer.save(sex=False) # 可以在save中,传递一些不需要验证的数据到模型里面
2)默认序列化器必须传递所有required的字段,否则会抛出验证异常。但是我们可以使用partial参数来允许部分字段更新
def get(self, request): """序列化器的基本使用:自动调用update修改数据""" # 模拟客户端提交过来的数据 data = { "name": "小明同学", "classmate": 305, "description": "hello world", "password": "456", "re_password": "456", } # 查询数据库,得到要修改的模型对象 student = Student.objects.get(pk=9) # partial=True 表示 对不存在的数据或客户端没有提供的数据,不需要按序列化器的字段列表进行验证。 serializer = StudentSerializer(instance=student, data=data, partial=True) serializer.is_valid(raise_exception=True) serializer.save(sex=False) # save源代码中,根据实例化序列化器时是否传递了instance, # 如果传递了instance参数,则serializer.save()会自动调用序列化器内部的update,并把instance与验证后的validated_data作为参数 # 如果没有传递instance参数,则serializer.save()会自动调用序列化器内部的create方法,并把验证后的validated_data作为参数 # 使用serializer.data实现序列化操作 return JsonResponse(serializer.data, status=201, safe=False)
三 模型类序列化器
如果我们想要使用序列化器对应的是Django的模型类,DRF为我们提供了ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类。
ModelSerializer与常规的Serializer的用法相同,但额外提供了:
-
基于模型类自动生成一系列序列化器字段
-
基于模型类自动为Serializer生成validators,比如unique_together
-
ModelSerializer默认包含了create()和update()的代码实现
⚠️ ModelSerializer内置了create与update方法,所以ModelSerializer在使用过程中,实际上不需要我们手写create与update方法的。而Serializer的源码中并没有内置create与update方法,所以我们如果要让Serializer实现数据保存功能,则务必实现create与update方法。
一 定义模型类序列化器
serializers.py,代码
from rest_framework import serializers class StudentModelSerializer(serializers.ModelSerializer): """学生信息模型类序列化器""" # 字段声明中可以覆盖从模型那边导入的字段声明[没有必要重写,只需要extra_kwargs中补充验证选项即可] # age = serializers.IntegerField(min_value=10) # 同时,也可以声明一些模型中没有的字段 password = serializers.CharField(write_only=True) re_password = serializers.CharField(write_only=True) class Meta: model = Student # 必填 # 务必把模型导入过的字段与上面的字段全部填入到fields的属性值,否则报错!! fields = ["id", "name", "age", "sex", "classmate", "password", "re_password"] # fields = "__all__" # 从模型中引入所有的字段序列化器中 read_only_fields = ["id", "sex"] # 只读字段列表,设置在这里的字段只会在序列化时使用到,不会被用于反序列化 extra_kwargs = { "age": {"min_value": 10, "max_value": 100}, "name": {"min_length": 4, "max_length": 16, "error_messages": { "min_length": "name字段的值长度必须是4个字符以上" }}, } def validate(self, attrs): """验证多个字段""" if attrs["password"] != attrs["re_password"]: raise serializers.ValidationError(detail="密码和确认密码不一致") # 可以在验证完成以后,把数据库中不需要的字典从attrs中移除 attrs.pop("password") attrs.pop("re_password") # 务必把验证后的内容返回给客户端 return attrs
Meta类里面的必填属性有2个:
-
model:指定当前序列化器类绑定的哪个模型类
-
fields:指定导入模型类的哪些字段到当前序列化器中作为序列化字段
视图代码,测试:
def get6(self,request): """模型类序列化器的基本使用:序列化1个模型""" student = Student.objects.first() serializer = StudentModelSerializer(instance=student) print(serializer) return JsonResponse(serializer.data) def get7(self,request): """模型类序列化器的基本使用:序列化多个模型""" student_list = Student.objects.all() serializer = StudentModelSerializer(instance=student_list, many=True) return JsonResponse(serializer.data, safe=False) def get(self,request): """模型类序列化器的基本使用:反序列化验证数据""" # 模拟客户端提交过来的数据 data = { "name": "hello", "classmate": 305, "age": 20, "description": "hello world", "password": "456", "re_password": "456", } serializer = StudentModelSerializer(data=data) print(serializer) serializer.is_valid(raise_exception=True) serializer.save() return JsonResponse(serializer.data, safe=False)
二 指定字段
1)使用fields
class StudentModelSerializer(serializers.ModelSerializer): """学生信息序列化器""" # 2. 如果当前序列化器继承的是ModelSerializer,则需要声明调用的模型信息 # 必须给Meta声明2个属性 class Meta: model = Student # 必填 fields = "__all__" # 必填,可以是字符串和列表/元组,字符串的值只能是"__all__"表示返回所有字段
2)使用exclude可以明确排除掉哪些字段不要从模型类导入过来,少用,与fields互斥的。
class StudentModelSerializer(serializers.ModelSerializer): """学生信息序列化器""" # 1. 转换的字段声明 # 字段名 = 字段类型(选项=选项值) nickname = serializers.CharField(read_only=True) # 2. 如果当前序列化器继承的是ModelSerializer,则需要声明调用的模型信息 # 必须给Meta声明2个属性 class Meta: model = Student # 必填 exclude = ['description'] # 排除,
3)显示指明字段,如:
class StudentModelSerializer(serializers.ModelSerializer): """学生信息序列化器""" # 1. 转换的字段声明 # 字段名 = 字段类型(选项=选项值) nickname = serializers.CharField(read_only=True) # 2. 如果当前序列化器继承的是ModelSerializer,则需要声明调用的模型信息 # 必须给Meta声明2个属性 class Meta: model = Student # 必填 fields = ["id", "name", "age", "sex","nickname"] # 必填,可以是字符串和列表/元组
4)指明指定字段,如:
可以通过read_only_fields指明只读字段,即仅用于序列化输出的字段
class StudentModelSerializer(serializers.ModelSerializer): """学生信息序列化器""" # 1. 转换的字段声明 # 字段名 = 字段类型(选项=选项值) nickname = serializers.CharField(read_only=True) # 2. 如果当前序列化器继承的是ModelSerializer,则需要声明调用的模型信息 # 必须给Meta声明2个属性 class Meta: model = Student # 必填 fields = ["id", "name", "age", "sex","nickname"] # 必填,可以是字符串和列表/元组,字符串的值只能是"__all__"表示返回所有字段 read_only_fields = ["id","sex"] # 选填,只读字段列表,表示设置这里的字段只会在序列化阶段采用
三 添加额外参数
我们可以使用extra_kwargs参数为ModelSerializer添加或修改原有的选项参数
class StudentModelSerializer(serializers.ModelSerializer): """学生信息序列化器""" # 1. 转换的字段声明 # 字段名 = 字段类型(选项=选项值) nickname = serializers.CharField(read_only=True) # 2. 如果当前序列化器继承的是ModelSerializer,则需要声明调用的模型信息 # 必须给Meta声明2个属性 class Meta: model = Student # 必填 fields = ["id", "name", "age", "sex","nickname"] # 必填,可以是字符串和列表/元组,字符串的值只能是"__all__"表示返回所有字段 read_only_fields = ["id","sex"] # 选填,只读字段列表,表示设置这里的字段只会在序列化阶段采用 extra_kwargs = { # 选填,字段额外选项声明 "age": { "min_value": 5, "max_value": 20, "error_messages": { "min_value": "年龄的最小值必须大于等于5", "max_value": "年龄的最大值必须小于等于20", } }, }
四 附
什么时候声明的序列化器需要继承序列化器基类Serializer,什么时候继承模型序列化器类ModelSerializer?
看客户端提交的数据是否与数据库模型相关,如果是则使用ModelSerializer,不是则使用Serializer,当然,即便和数据库相关,我们偏要使用Serializer,也没有问题。
继承序列化器类Serializer 字段声明 验证 添加/保存数据功能 继承模型序列化器类 ModelSerializer 字段声明[可选,看需要] Meta声明[必填] 验证 添加/保存数据功能[可选,看需要,例如一次性添加数据到多个模型中]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现