标签:return name author self publish 序列化 Serializer
常用字段类和字段参数
1.
CharField
BooleanField
IntegerField
DecimalField
2.返回格式
ListField:
{hobby: ['篮球', '足球']}
DictField:
{wife: {'name': 'barry'}}
参数名称 |
作用 |
max_length |
最大长度 |
min_lenght |
最小长度 |
allow_blank |
是否允许为空 |
trim_whitespce |
是否截断空白字符 |
max_value |
最小值 |
min_value |
最大值 |
参数名称 |
作用 |
required |
该字段在反序列化时必须输入,默认为True |
default |
反序列化时使用的默认值 |
allow_null |
该字段是否允许传入None,默认为False |
validators |
该字段使用的验证器 |
error_messages |
包含错误编号与错误信息的字典 |
label |
用于HTML展示API页面时,显示的字段名称 |
help_text |
用于HTML展示API页面时,显示的字段帮助提示信息 |
read_only |
该字段仅用于序列化输出,默认为False |
write_only |
该字段仅用于反序列化输入,默认为False |
序列化字段参数sourec的使用
1.name字段在前端显示的时候叫book_name
book_name = serializers.CharField(max_length=8, min_length=3, source='name')
'source字段可以指定序列化表中那个字段'
2.source指定的可以是字段也可以是方法,用于重命名
book_name = serializers.CharField(max_length=8, min_length=3, source='sb_name')
def sb_name(self):
return 'sb' + self.name
'source可以做跨表查询'
表模型和数据录入
-在前端显示
[
{
"name": "西游记",
"price": 30,
"publish": {
"name": "广州出版社",
"city": "广州",
"email": "[email protected]"
}
}
]
1.方法1:在序列化类中使用SerializerMethodField
publish = serializers.SerializerMethodField()
def get_publish(self, obj):
# obj是当前序列化的对象
return {'name': obj.publish.name,
'city': obj.publish.city,
'email': obj.publish.email}
2.方法2:在表模型中写方法
def publish_detail(self):
return {'name': self.publish.name,
'city': self.publish.city,
'email': self.publish.email}
# 序列化中
publish_detail = serializers.DictField()
'在模型类中写逻辑代码,称之为ddd,领域驱动模型'
多表基于Serializer反序列化
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
publish_date = models.DateField(null=True)
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
author = models.ManyToManyField(to='Author')
def __str__(self):
return self.name
def publish_detail(self):
return {'name': self.publish.name,
'city': self.publish.city,
'email': self.publish.email}
class BookSerializer(serializers.Serializer):
# 要序列化字段
name = serializers.CharField(max_length=8, min_length=3)
price = serializers.IntegerField(max_value=99, min_value=10)
# 反序列化
publish = serializers.IntegerField(write_only=True)
author = serializers.ListField(write_only=True)
# 序列化
publish_detail = serializers.DictField(read_only=True)
author_list = serializers.ListField(read_only=True)
# 要重写create
def create(self, validated_data):
# validated_data是校验后的数据
book = Book.objects.create(name=validated_data.get('name'),
price=validated_data.get('price'),
publish_date=validated_data.get('publish_date'),
publish_id=validated_data.get('publish'))
author = validated_data.get('author')
book.author.add(*author)
return book
ModelSerializer的使用
继承Serializer的序列化类,在序列化的每个字段无论是序列化还是反序列化都要写,如果是新增或修改,都需要重写create、update
'可以使用ModelSerializer来做'
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
# 要序列化的表模型
model = Book
# 所有字段都序列化
# fields = '__all__'
# 列表说什么就序列化那个字段
fields = ['name', 'price', 'publish_date', 'publish', 'author', 'publish_list', 'author_list']
# 给author和publish加write_only属性,给name加max_length属性
extra_kwargs = {'name': {'max_length': 8},
'publish': {'write_only': True},
'author': {'write_only': True},
}
publish_list = serializers.SerializerMethodField(read_only=True)
def get_publish_list(self, obj):
return {'name': obj.publish.name, 'city': obj.publish.city, 'email': obj.publish.email}
author_list = serializers.SerializerMethodField(read_only=True)
def get_author_list(self, obj):
res = []
for author in obj.author.all():
res.append({'id': author.id, 'name': author.name, 'age': author.age})
return res
反序列化之数据校验
-使用
1.定义一个类继承ModelSerializer
2.类内部写class Meta:
3.在内部类中指定model,也就是要序列化的表
4.在内部类中指定fields,fields是要序列化的字段,不写fields写__all__表示所有,不包含方法
5.在内部指定extra_kwargs,给字段添加字段参数
6.在序列化类中可以重写某个字段
name = serializers.SerializerMethodField()
def get_name(self, obj):
return 'sb' + obj.name
7.不需要重写create、update
1.反序列化有字段自己的校验规则、局部钩子、全局钩子
class BookModelSerializer(serializers.ModelSerializer):
class Meta:
# 要序列化的表模型
model = Book
# 列表说什么就序列化那个字段
fields = ['name', 'price', 'publish_date', 'publish', 'author']
# 继承ModelSerializer时给name加属性
extra_kwargs = {'name': {'max_length': 8, 'min_length': 3,
'error_messages': {'min_length': "太短了"}},
'price': {'max_value': 100, 'min_value': 3},
'publish': {'write_only': True},
'author': {'write_only': True},
}
# 局部钩子
def validate_name(self, name):
if name.startswith('sb'):
# 校验不通过抛异常
raise ValidationError('不能以sb卡头')
else:
return name
# 全局钩子
def validate(self, attrs):
if attrs.get('name') == attrs.get('publish_date'):
raise ValidationError('名字不能等于日期')
else:
return attrs
作业
#1 所有人写出book表(带关联关系)5 个接口
Serializer
ModelSerializer(简单,不用重写create和update)
name最大8,最小3,名字中不能带sb
price最小9,最大199,不能为66
#2 出版社,作者,作者详情 5个接口写完(ModelSerializer好些一些
class BookModelSerializer(serializers.ModelSerializer):
# price = serializers.DecimalField()
class Meta:
# 要序列化的表模型
model = Book
# 列表说什么就序列化那个字段
fields = ['name', 'price', 'publish_date', 'publish', 'author']
# 继承ModelSerializer时给name加属性
extra_kwargs = {'name': {'max_length': 8, 'min_length': 3,
'error_messages': {'min_length': "太短了"}},
'price': {'max_value': 199, 'min_value': 9},
'publish': {'write_only': True},
'author': {'write_only': True},
}
# 局部钩子
def validate_name(self, name):
if name.startswith('sb'):
# 校验不通过抛异常
raise ValidationError('不能以sb卡头')
else:
return name
def validate_price(self, price):
if price == 66:
# 校验不通过抛异常
raise ValidationError('不能是66')
else:
return price
class BookView(APIView):
def get(self, request):
book_list = Book.objects.all()
ser = BookModelSerializer(instance=book_list, many=True)
return Response(ser.data)
def post(self, request):
ser = BookModelSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '新增成功'})
else:
return Response({'code': 101, 'msg': ser.errors})
class BookDataView(APIView):
def get(self, request, pk):
book = Book.objects.filter(pk=pk).first()
ser = BookModelSerializer(instance=book)
return Response(ser.data)
def put(self, request, pk):
book = Book.objects.filter(pk=pk).first()
ser = BookModelSerializer(instance=book, data=request.data)
if ser.is_valid():
ser.save()
return Response(ser.data)
else:
return Response({'code': 101, 'msg': ser.errors})
def delete(self, request, pk):
Book.objects.filter(pk=pk).delete()
return Response()
标签:return,
name,
author,
self,
publish,
序列化,
Serializer
From: https://www.cnblogs.com/riuqi/p/16736486.html