django序列化器使用
转载自:。
原文链接:https://blog.csdn.net/weixin_49278803/article/details/122846938
一、Serializer
1.1、serializer序列化分为两种:正向序列化(序列化)&反向序列化(反序列化)
- 序列化即将数据库对象转换成数据,可实现数据的可视化输出以及更为高级的定制化输出
- 反序列化即将数据转换成序列化对象,进而将其存入数据库,可实现字段的校验
1.2、无论是序列化还是反序列化既可以使用SerializerMethodField也可以使用ModelSerializer
- 引入方式
from rest_framework.serializers import Serializer,ModelSerializer
二、操作模式
2.1、Serializer序列化
# 以AuthorDetail表为例子
def phone_rule(data): # data就是字段tel对应的数据
"""自定义手机号验证规则"""
pass
class AuthorDetailSercodializer(Serializer):
id = serializers.IntegerField(label="主键", read_only=True, error_messages={"required": "read_only为真,表示此字段只在序列化时做检查,反序列化不做检查"})
addr = serializers.CharField(label="住址", error_messages={"required": "地址字段addr不能为空"})
tel = serializers.IntegerField(label="联系方式", error_messages={"required": "联系方式字段tel不能为空"}, validators=[phone_rule, ])
#使用Serializer时候必须重写create方法
def create(self, validated_data):
# validated_data.pop("key")
res = models.AuthorDetail.objects.create(**validated_data)
return res
# 使用Serializer时候必须重写update方法
def update(self, instance, validated_data):
try:
models.AuthorDetail.objects.filter(pk=instance.id).update(**validated_data)
return {"code": 200, "msg": "成功"}
except Exception as e:
return {"code": 400, "msg": "失败", "error": e}
# 可以写局部钩子对部分字段校验,函数命名规则"validate_字段名"
def validate_tel(self, data):
pass
# 也可以写全局钩子,函数命令规则validate
def validate(self, attr): # 先校验局部再校验全局钩子
# addr = attr.get("addr")
# tel = attr.get("tel")
pass
2.2、ModelSerializer序列化
# 以Author表为例
class AuthorSerializer(ModelSerializer):
class Meta:
model = models.Author
# --------------------------------------START序列化字段介绍--------------------------------
# 指定序列化字段方式一(2选1):
# fields = ["id", "name", "age", "author_detail"] # 因books是Authoro类里面的一个属性,不是字段
# 指定序列化字段方式二(2选1):
field = "__all__"
# 剔除部分字段不显示(只能在序列化字段方式一使用,即只与field配合使用)
# exclude = ["name", "author_detail"]
exclude = []
# --------------------------------------END序列化字段介绍--------------------------------
# 深度:假设C表关联B表,B表关联A表,对应关系均为一对多:A-B,B-C。深度1即序列化C表会触及到B表,深度2即序列化C表不仅会触及到B表还会由此触及到A表
depth = 1
# 可以写局部钩子对部分字段校验,函数命名规则"validate_字段名"
def validate_tel(self, data):
pass
# 也可以写全局钩子,函数命令规则validate
def validate(self, attr): # 先校验局部再校验全局钩子
# addr = attr.get("addr")
# tel = attr.get("tel")
pass
三、如何在序列化中增加自定义字段?
3.1、增加自定义字段方式一source:依赖于已有字段。序列化正常调用,反序列化不执行。正反序列化类可合二为一
# 参照2.1,采用Serializer序列化
customField = serializers.CharField(error_messages={"required": "自定义字段,取值来源于source,即addr值"}, read_only=True, source="addr")
# 参照2.2,采用ModelSerializer序列化
customField = serializers.CharField(error_messages={"required": "自定义字段,取值来源于source,即name值"}, read_only=True, source="name")
3.2、增加自定义字段方式二SerializerMethodField:序列化正常调用,反序列化不执行。正反序列化类可合二为一
# 参照2.1,采用Serializer序列化
customField = serializers.SerializerMethodField()
def get_customField(self, obj):
return {"name2.1": "测试序列化自定义新增字段"}
# 参照2.2,采用ModelSerializer序列化
customField = serializers.SerializerMethodField()
def get_customField(self, obj):
return {"name2.2": "测试序列化自定义新增字段"}
3.3、增加自定义字段方式三PrimaryKeyRelatedField:只有是外键字段才可以使用PrimaryKeyRelatedField进行增加自定义字段操作。序列化正常调用,反序列化不执行。正反序列化类可合二为一
# 以Book表为例子,采用Serializer序列化 class BookSerializers(Serializer): id = serializers.IntegerField(label="主键", read_only=True, error_messages={"required": "read_only为真,表示此字段只在序列化时做检查,反序列化不做检查"}) name = serializers.CharField(label="书名", error_messages={"required": "书名字段name不能为空"}) price = serializers.DecimalField(label="价格", max_digits=6, decimal_places=2, error_messages={"required": "价格字段price不能为空"}) publish = serializers.PrimaryKeyRelatedField(label="出版社", queryset=models.Book.objects.all(), error_messages={"required": "出版社ID字段publish不能为空"}) # 可以增加属性default=models.Book.objects.first().id # 调通用方法:对结果publish="主键id" 格式化 返回publish模型数据 def to_representation(self, obj): # 此函数在序列化时才会用到,用于自定义输出 ret = super(BookSerializers, self).to_representation(obj) ret["publish"] = { "name": obj.publish.name, "addr": obj.publish.addr } return ret
# 以Book表为例子,采用ModelSerializer序列化 class BookSerializers(ModelSerializer): class Meta: model = models.Book field = "__all__" exclude = [] # 重新publish赋值 publish = serializers.PrimaryKeyRelatedField(label="出版社", queryset=models.Book.objects.all(), error_messages={"required": "出版社ID字段publish不能为空"}) # 可以增加属性default=models.Book.objects.first().id # 调通用方法:对结果publish="主键id" 格式化 返回publish模型数据 def to_representation(self, obj): # 此函数在序列化时才会用到,用于自定义输出 ret = super(BookSerializers, self).to_representation(obj) ret["publish"] = { "name": obj.publish.name, "addr": obj.publish.addr } return ret
3.4、增加自定义字段方式四"继承自身":只可用于正向序列化即不可以在反序列化中使用。正反序列化类不可合二为一
# 以Book表为例子,publish字段继承于Publish序列化,采用Serializer序列化 class PublishSerializers(Serializer): id = serializers.IntegerField(label="主键", read_only=True, error_messages={"required": "read_only为真,表示此字段只在序列化时做检查,反序列化不做检查"}) name = serializers.CharField(label="出版社名", error_messages={"required": "出版社字段name不能为空"}) addr = serializers.CharField(label="地址", error_messages={"required": "地址字段addr不能为空"}) # book_set = serializers.StringRelatedField(many=True) # book_set为反向查询名称,通过这个可以将反向数据导出,不常用哟,不做过多描述,了解即可 class BookSerializers(Serializer): id = serializers.IntegerField(label="主键", read_only=True, error_messages={"required": "read_only为真,表示此字段只在序列化时做检查,反序列化不做检查"}) name = serializers.CharField(label="书名", error_messages={"required": "书名字段name不能为空"}) price = serializers.DecimalField(label="价格", max_digits=6, decimal_places=2, error_messages={"required": "价格字段price不能为空"}) publish = PublishSerializers(many=False)
# 以Book表为例子,publish字段继承于Publish序列化, 采用ModelSerializer序列化 class PublishSerializers(ModelSerializer): class Meta: model = models.Publish field = "__all__" exclude = [] # book_set = serializers.StringRelatedField(many=True) # book_set为反向查询名称,通过这个可以将反向数据导出,不常用哟,不做过多描述,了解即可 class BookSerializers(ModelSerializer): class Meta: model = models.Book field = "__all__" exclude = [] # 重新publish赋值 publish = PublishSerializers(many=False)
四、调用方式
- 假设数据库表为A,序列化类|反序列化类均为ASerializers,反序列化数据dataDict = {“name”: “test”}
4.1、序列化
obj = models.A.objects.get(id=1)
# objs = models.A.objects.all()
objSr = ASerializers(instance=obj) # 检查objSr的属性data
# objSr = ASerializers(instance=objs, many=True)
print(objSr.data)
4.2、反序列化
添加数据
objSr = ASerializers(data=dataDict)
# objSr.is_valid(raise_exception=True)
objSr.is_valid() # 反序列时必须执行is_valid方法。校验成功,则数据为objSr.validated_data;校验失败,错误信息在objSr.errors中,同时属性validated_data为{}
print(objSr.validated_data)
objSr.save() # 会自动跳转到重写的方法create中
更新数据
obj = models.A.objects.get(pk=1)
objSr = ASerializers(instance=obj, data=dataDict)
# objSr.is_valid(raise_exception=True)
objSr.is_valid() # 反序列时必须执行is_valid方法。校验成功,则数据为objSr.validated_data;校验失败,错误信息在objSr.errors中,同时属性validated_data为{}
print(objSr.validated_data)
objSr.save() # 会自动跳转到重写的方法update中
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?