序列化器的使用
一对多查询
方式1 获取多表中关联的主键id
serializer
# 自定义序列化器
class BookSerialzier(serializers.Serializer):
# 序列化返回字段
btitle = serializers.CharField(max_length=20, min_length=5, write_only=True)
bread = serializers.IntegerField(max_value=100, min_value=5)
bpub_date = serializers.DateField()
bcomment = serializers.IntegerField(default=10)
# 返回多表中关联的英雄id PrimaryKeyRelatedField
heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True,many=True)
结果展示
[
{
"bread": 89,
"bpub_date": "2021-07-03",
"bcomment": 110,
"heroinfo_set": [
1,
2,
3,
4
]
},
{
"bread": 99,
"bpub_date": "2021-07-01",
"bcomment": 11,
"heroinfo_set": [
5,
6
]
},
{
"bread": 79,
"bpub_date": "2021-05-01",
"bcomment": 81,
"heroinfo_set": [
7
]
}
]
方式2 获取多表中关联的str方法值
serializer
# 自定义序列化器
class BookSerialzier(serializers.Serializer):
# 序列化返回字段
btitle = serializers.CharField(max_length=20, min_length=5, write_only=True)
bread = serializers.IntegerField(max_value=100, min_value=5)
bpub_date = serializers.DateField()
bcomment = serializers.IntegerField(default=10)
# 返回关联的英雄id PrimaryKeyRelatedField
# heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
# 返回多表中关联英雄模型类的str方法值
heroinfo_set = serializers.StringRelatedField(read_only=True, many=True)
结果展示
[
{
"bread": 89,
"bpub_date": "2021-07-03",
"bcomment": 110,
"heroinfo_set": [
"曹操",
"周瑜",
"刘备",
"貂蝉"
]
},
{
"bread": 99,
"bpub_date": "2021-07-01",
"bcomment": 11,
"heroinfo_set": [
"孙悟空",
"白骨精"
]
},
{
"bread": 79,
"bpub_date": "2021-05-01",
"bcomment": 81,
"heroinfo_set": [
"潘金莲"
]
}
]
方式3 自定义多表的序列化器可以获得想要的多表中的字段
serializer
新建多表的序列化器
class HeroInfoSerialzier(serializers.Serializer):
# 英雄序列化器
hname = serializers.CharField()
hcomment = serializers.CharField()
class BookSerialzier(serializers.Serializer):
# 图书序列化器
btitle = serializers.CharField(max_length=20, min_length=5, write_only=True)
bread = serializers.IntegerField(max_value=100, min_value=5)
bpub_date = serializers.DateField()
bcomment = serializers.IntegerField(default=10)
heroinfo_set = HeroInfoSerialzier(many=True)
注意:HeroInfoSerialzier必须先于BookSerialzier,否则报错
结果展示
[
{
"bread": 89,
"bpub_date": "2021-07-03",
"bcomment": 110,
"heroinfo_set": [
{
"hname": "曹操",
"hcomment": null
},
{
"hname": "周瑜",
"hcomment": null
},
{
"hname": "刘备",
"hcomment": null
},
{
"hname": "貂蝉",
"hcomment": null
}
]
},
{
"bread": 99,
"bpub_date": "2021-07-01",
"bcomment": 11,
"heroinfo_set": [
{
"hname": "孙悟空",
"hcomment": null
},
{
"hname": "白骨精",
"hcomment": null
}
]
},
{
"bread": 79,
"bpub_date": "2021-05-01",
"bcomment": 81,
"heroinfo_set": [
{
"hname": "潘金莲",
"hcomment": null
}
]
}
]
选项参数方法验证
serialzier
如字段max_length=20最大长度20, min_length=5最小长度5,write_only=True只参与反序列化,read_onle=True只参与序列化,required=True必传,default=10默认值为10,unique=True唯一值
class BookSerialzier(serializers.Serializer):
# 序列化返回字段
btitle = serializers.CharField(max_length=20, min_length=5, write_only=True)
bread = serializers.IntegerField(max_value=100, min_value=5)
bpub_date = serializers.DateField()
bcomment = serializers.IntegerField(default=10)
view
需要调用is_valid()方法来验证字段
class BookDRFView(View):
"""
单一更新和删除
"""
def put(self, request, pk):
# 1、获取前端数据
data = request.body.decode()
data_dict = json.loads(data)
# 2、验证数据
try:
book = BookInfo.objects.get(id=pk)
except:
return JsonResponse({'error': '错误信息'}, status=400)
ser=BookSerialzier(book,data=data_dict)
ser.is_valid()
# 3、更新数据
ser.save()
# 4、返回结果
return JsonResponse(ser.data)
自定义方法验证
class BookSerialzier(serializers.Serializer):
# 序列化返回字段
btitle = serializers.CharField(max_length=20, min_length=5, write_only=True)
bread = serializers.IntegerField(max_value=100, min_value=5)
bpub_date = serializers.DateField()
bcomment = serializers.IntegerField(default=10)
# 返回关联的英雄id PrimaryKeyRelatedField
# heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
# 返回关联英雄模型类的str方法值
# heroinfo_set = serializers.StringRelatedField(read_only=True, many=True)
heroinfo_set = HeroInfoSerialzier(many=True)
# 单一字段验证
# validate_字段名 格式固定死了,不然无效
def validate_btitle(self, value):
if value == '黄色':
raise serializers.ValidationError('书名不能是黄色')
return value
# 多个字段验证
def validate(self, attrs):
if attrs['bread'] < attrs['bcomment']:
raise serializers.ValidationError('阅读量大于评论量')
return attrs
view中获取验证后的数据validated_data
def post(self, request):
# 1、获取前端数据
data = request.body.decode()
data_dict = json.loads(data)
# 2、验证数据
ser = BookSerialzier(data=data_dict)
ser.is_valid() # 验证方法
print(ser.validated_data) # 获取验证后的字段数据
# 3、保存数据
ser.save()
# 4、返回结果
return JsonResponse(ser.data)
保存数据
view中save()保存数据
def post(self, request):
# 1、获取前端数据
data = request.body.decode()
data_dict = json.loads(data)
# 2、验证数据
ser = BookSerialzier(data=data_dict)
ser.is_valid() # 验证方法
print(ser.validated_data) # 获取验证后的字段数据
# 3、保存数据
ser.save()
# 4、返回结果
return JsonResponse(ser.data)
Serialzier中create拆包保存
def create(self, validated_data):
# 保存数据
book = BookInfo.objects.create(**validated_data)
return book
更新
view 注意BookSerialzier参数
def put(self, request, pk):
# 1、获取前端数据
data = request.body.decode()
data_dict = json.loads(data)
# 2、验证数据
try:
book = BookInfo.objects.get(id=pk)
except:
return JsonResponse({'error': '错误信息'}, status=400)
ser=BookSerialzier(book,data=data_dict)
ser.is_valid()
# 3、更新数据
ser.save()
# 4、返回结果
return JsonResponse(ser.data)
Serialzier
def update(self, instance, validated_data):
# 更新数据
instance.btitle = validated_data['btitle']
instance.bread = validated_data['bread']
instance.save()
return instance
ModelSerializer
class BookModelSerialzier(serializers.ModelSerializer):
# 显示指明字段
bread=serializers.IntegerField(max_value=100,min_value=20)
sms_code=serializers.CharField(max_length=6,min_length=6)
class Meta:
model=BookInfo # 指定生成字段的模型类
fields=('btitle','bread','sms_code') # 指定模型类中的字段
# fields='__all__' # 指定模型类中的字段
read_only_fields=('btitle',)
# exclude=('btitle',) # 排除模型类中的字段
# 添加修改字段选项参数
# extra_kwargs={
# "bcomment":{
# 'max_value':100
# },
# 'btitle':{
# 'min_length':5
# }
#
# }
# def validate(self, attrs):
#
#
# def validate_btitle(self, data):