序列化与反序列化
作用:
定义序列化器:序列化器必须要直接继承或者间接结成serializers.Serializer,Serializer有个子类ModelSerializer
使用教程
1
序列化的使用:不仅可以转换模型对象的数据格式,python中的对象的属性对应序列化器的字段也可以转换为字典或者列表
序列化器编写:
from rest_framework import serializers class StudentSerializer(serializers.Serializer): """学生信息序列化器""" # 1.声明请求与响应过程中的字段 id = serializers.IntegerField() name = serializers.CharField() age = serializers.IntegerField() sex = serializers.BooleanField() description = serializers.CharField() # 2.序列化器用的是ModelSerializer,则需要声明Meta # 3.验证代码 # 4.编写数据库模型的添加与更新代码
视图编写:
""" 暂时使用django中的原生views,未使用drf视图类 """ from FRAMEWORK.models import Student # 使用Student的模型 from django.shortcuts import render from sers.serializers import StudentSerializer # 导入序列化器 from django.views import View from django.http.response import JsonResponse class StudentView1(View): def get(self, request): # 查询单条数据 """序列化器序列化阶段使用: 实例化序列化器得到序列化对象 参数:serializer=StudentSerializer( instance=本次转换数据格式的数据 来自数据库 模型类[单个]/查询集[多个] date=需要进行数据转换的数据 来自客户端 字典/者列表 contest={}:从视图中传递给序列化器的第三方数据(比如request) 字典 many=设置本次转换的数据是否为多条数据(决定了序列化器能否用for进行数据转换,True/False) ) """ # 查询单条数据 # serializer = StudentSerializer(instance=student) # 查询多条数据 # serializer = StudentSerializer(instance=student_list,many=True) # 更新一条 # serializer = StudentSerializer(instance=student,date=date) # 添加一条数据 # serializer = StudentSerializer(date=date) # 删除一条数据 # 一般不使用序列化器 student = Student.objects.first() # 查询数据 serializer = StudentSerializer(instance=student) # 序列化数据 # 转换后的数据其实是:serializer.data return JsonResponse(serializer.data) # def get(self, request): # """查询多条数据""" # student_list = Student.objects.all() # serializer = StudentSerializer(instance=student_list, many=True) # # print(serializer.data)#有序字典OrderedDict写入读取时顺序一致 # return JsonResponse(serializer.data, safe=False) # 为了允许序列化非dict对象,将safe参数设置为False
反序列化的使用
数据验证:验证后在反序列化保存为模型对象
在反序列化前需要调用 序列化对象的is_valid() 方法进行序列化内部的预设的代码教验,返回True/False,
失败时,可以通过 序列化对象的errors 属性获取错误信息(字典格式),若是非字段错误,通过rest_framework提供的配置:NOT_FIELDS_ERRORS_KEY控制错误字典中的键值
成功后:通过 序列化器对象的validated_data属性获取验证后的数据
def get(self, request): """反序列化:用户添加或者更新数据时使用""" # 模拟用户传来的数据 data = { "name": "小明", "age": 17, "sex": 1, "description": "懒人一枚", } # 反序列化操作 serializer = StudentSerializer(data=data) # 错误信息两种方式 # 方式1: # raise_exception=True,失败时drf自动抛出异常 # serializer.is_valid(raise_exception=True) ret = serializer.is_valid() print(ret) if ret: # 获取验证后的结果 print(f"serializer.validated={serializer.validated_data}") # 方式2:我们需要捕获错误信息 else: # 获取报错结果 print(f"serializer.errors={serializer.errors}") # 拆分一下报错结果 for item in serializer.errors.items(): print(f"错误字段={item[0]}") for error in item[1]: print(f"错误处={error.code}") print(f"错误原因={error}") return JsonResponse({"msg": "ok"})
is_valid()调用了数据声明的验证方法,添加更多验证方法使用下列三种方法
1)validate_字段名
# 3.1 单字段补充验证: def validate_name(self, data): """ 必须以"validate_<字段名>"作为方法名 必须返回此字段,回传序列化器,否则数据丢失,可以改动,必须返回 :param data:接收验证字段(名字随意) :return: """ print(f"validate_name验证字段:{data}") if data == "java": # 序列化器抛出异常可以通过 raise serializers.ValidationError(code="name", detail="当前字段为敏感字眼") return data
2)validate
# 3.2 多字段验证(只能由1个或者0个) def validate(self, attrs): """ 必须以"validated"作为方法名 会接收客户端所有字段数数 必须返回此字段,否则丢失 :return: """ # 多字段一般用于用户注册时密码与确认密码的2个字段必须一样此类情况(因为request并没有传过来) age = attrs.get("age") sex = attrs.get("sex") if sex != 3 and age <= 18: raise serializers.ValidationError("年龄18以下的,性别应该保密") return attrs
- 3)validators
-
# 3.3单字段验证函数
age = serializers.IntegerField(validators=[Adulted])
sex = serializers.ChoiceField(choices=SEX_OPTIONS, validators=[NoNum])
def Adulted(data): if data < 10: raise serializers.ValidationError("年龄低于10不能使用本产品") return data def NoNum(data): if data > 3 or data < 1: raise serializers.ValidationError("sex只能出现指定数字") return data - 反序列化-保存数据
- 解释,如果在调用save()方法时没有传入instance(也就是下列添加数据),就会调用序列化器中的create()方法,
- 传入了instance对象(更新操作)则会调用序列化器中的update()方法
- 同时针对特殊场景:例如注册与修改时使用同一序列化器,修改不需要填写其他信息,允许部分字段的更新,允许使用partial参数进行部分更新
-
data = { "name": "工三", "age": 21, "sex": 1, "description": "描述2", "class_null": "101", } # 获取本次修改模型对象 student = Student.objects.get(pk=pk) serializer = StudentSerializer(instance=student, data=data,partial=True)
- 第一种:添加数据
def get5(self, request): """添加数据反序列化时,调用模型保存数据""" # 模拟用户传来的数据 data = { "name": "ofa", "age": 19, "sex": 2, "class_null": "23", "description": "无", } serializer = StudentSerializer(data=data) serializer.is_valid(raise_exception=True) # 调用save方法模型存储数据(序列化器内部的save不是django的) student = serializer.save() # 接收Student对象,可操作 print(serializer.data) return JsonResponse({"msg": "保存了吗?"}) #但是.save()方法并不适用,需要在序列化器中重写 # 视图调用序列化器的save时要写create方法,否则报错 def create(self, validated_data): """添加数据 到模型中的实现方法 所有数据都是预先校验过直接添加即可 """ # 添加数据完全属于模型 # student=Student.objects.create(**validated_data) # 存在字段不属于模型,指定字段即可 student = Student.objects.create( name=validated_data.get("name"), age=validated_data.get("age"), sex=validated_data.get("sex"), class_null=validated_data.get("class_null") ) # 强烈建议返回添加后的模型对象 return student
- 第二种更新数据
-
def get6(self, request): """更新数据反序列化时,调用模型保存数据 restful中规定:修改删除数据需要pk值,写在url中 """ pk = 3 data = { "name": "工三", "age": 21, "sex": 1, "description": "描述2", "class_null": "101", } # 获取本次修改模型对象 student = Student.objects.get(pk=pk) serializer = StudentSerializer(instance=student, data=data) serializer.is_valid(raise_exception=True) serializer.save() print(serializer.data) # 再次序列化将更新数据返回客户端 return JsonResponse({"msg": "更新好了吗?"}) def update(self, instance, validated_data): """ :param instance: 本次更新数据库模型 :param validated_data:客户端提价的已验证的数据 :return: """ instance.name = validated_data.get("name") instance.age = validated_data.get("age") instance.sex = validated_data.get("sex") instance.class_null = validated_data.get("class_null") # 可选字段单独验证一下 if validated_data.get("description"): instance.description = validated_data.get("description") # 调用模型的save方法 instance.save() return instance
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南