继上篇讲了django orm表建立,那不得不再讲一下django(drf)序列化serializer
from rest_framework.serializers import Serializer,ModelSerializer
# 以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
# 以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
# 参照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")
# 参照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": "测试序列化自定义新增字段"}
# 以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
# 以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)
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)
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中