序列化常用字段、字段参数、source、定制字段的两种方法、ModelSerializer使用
序列化常用字段
字段 | 字段构造方式 |
---|---|
BooleanField | BooleanField() |
NullBooleanField | NullBooleanField() |
CharField | CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True) |
EmailField | EmailField(max_length=None, min_length=None, allow_blank=False) |
RegexField | RegexField(regex, max_length=None, min_length=None, allow_blank=False) |
SlugField | SlugField(max_length=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+ |
URLField | URLField(max_length=200, min_length=None, allow_blank=False) |
UUIDField | UUIDField(format=’hex_verbose’) format: 1) 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) 'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a" 3)'int' - 如: "123456789012312313134124512351145145114" 4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a" |
IPAddressField | IPAddressField(protocol=’both’, unpack_ipv4=False, **options) |
IntegerField | IntegerField(max_value=None, min_value=None) |
FloatField | FloatField(max_value=None, min_value=None) |
DecimalField | DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置 |
DateTimeField | DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None) |
DateField | DateField(format=api_settings.DATE_FORMAT, input_formats=None) |
TimeField | TimeField(format=api_settings.TIME_FORMAT, input_formats=None) |
DurationField | DurationField() |
ChoiceField | ChoiceField(choices) choices与Django的用法相同 |
MultipleChoiceField | MultipleChoiceField(choices) |
FileField | FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
ImageField | ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
重要字段:
字段 | 字段构造 |
---|---|
CharField | CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True) |
IntegerField | IntegerField(max_value=None, min_value=None) |
DecimalField | DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置 |
DateTimeField | DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None) |
BooleanField | BooleanField() |
ListField | ListField(child=, min_length=None, max_length=None) |
DictField | DictField(child=) |
常用字段参数
CharField及其子类的(EmailField)-- 反序列化的检验 字段自己的规则
字段 | 字段名 |
---|---|
max_length | 最大长度 |
min_length | 最短长度 |
allow_blank | 是否允许为空 |
trim_whitespace | 是否截断空白字符 |
IntegerField字段
字段 | 字段名 |
---|---|
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 |
序列化高级用法-source
创建表关系:
class Books(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32)
publish = models.ForeignKey(to="Publish", on_delete=models.CASCADE)
books2author = models.ManyToManyField(to="Author")
class Publish(models.Model):
name = models.CharField(max_length=32)
add = models.CharField(max_length=32)
class Author(models.Model):
name = models.CharField(max_length=32)
phone = models.CharField(max_length=32)
迁移,录入数据:
1.序列化定制字段名字 source=
重点:source可以指定序列化字段的名字
name1 = serializers.CharField(source='name')
#自有字段可以直接写名字
publish_id = serializers.CharField(source='publish.name')
#关联字段 一对多 直接点名字
author = serializers.CharField(source='books2author.all')
#关联字段 多对多 source用不了
序列化高级用法-定制字段的两种方法
1.SerializeMethodField定制
定制关联字段的显示形式:
一对多--显示字典
多对多--显示列表套字典
#一对多
publish_id = serializers.SerializerMethodField()
def get_publish_id(self,obj):
return {'name':obj.publish.name,'addr':obj.publish.add}
#多对多
author = serializers.SerializerMethodField()
def get_author(self,obj):
l = []
for author in obj.books2author.all():
l.append({'name':author.name,'phone':author.phone})
return l
2.在表模型中定制
models.py
class Books(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32)
publish = models.ForeignKey(to="Publish", on_delete=models.CASCADE)
books2author = models.ManyToManyField(to="Author")
def publish_dict(self):
return{'name':self.publish.name,'price':self.publish.add}
def author_list(self):
l = []
for author in self.books2author.all():
l.append({'name':author.name,'phone':author.phone})
return l
'''
外键在哪个表下面 就在那个表下面定制
'''
serializer.py
class BookSerializer(serializers.Serializer):
name1 = serializers.CharField(max_length=8,min_length=2,source='name')
price = serializers.CharField()
publish_dict = serializers.DictField()
author_list = serializers.ListField()
多表关联反序列化保存
1.新增图书接口
前端传入数据格式:{'name':'红楼梦','price':'19','publish':1,'author':[1,2]}
views.py
def post(self,request):
ser = BookSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code':100,'msg':'添加成功'})
else:
return Response({'code':101,'msg':'添加失败'})
serializer.py
class BookSerializer(serializers.Serializer):
#name和price既用来序列化 有用来反序列化 既写又读 不用加read_only或write_only
name = serializers.CharField()
price = serializers.CharField()
#序列化 只读模式
publish_dict = serializers.DictField(read_only=True)
author_list = serializers.ListField(read_only=True)
#反序列化 只写模式
publish = serializers.CharField(write_only=True)
author = serializers.ListField(write_only=True)
#新增要重写create方法
def create(self, validated_data):
#validated_data校验过后的数据是{name:红楼梦,price:19,publish:1,authors:[1,2]}
book = Books.objects.create(name=validated_data.get('name'),price=validated_data.get('price'),publish_id=validated_data.get('publish'))
#关联作者 打散获取到的列表数据 获取作者
book.books2author.add(*validated_data.get('author'))
return book
2.修改图书接口
前端传入数据格式:{'name':'红楼梦','price':'19','publish':1,'author':[1,2]}
views.py
class BooksViews(APIView):
def put(self,request,pk):
book = Books.objects.filter(pk=pk).first()
ser=BookSerializer(instance=book,data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '修改成功'})
else:
return Response({'code': 101, 'msg': ser.errors})
serializer.py
def update(self, instance, validated_data):
instance.name = validated_data.get('name')
instance.price = validated_data.get('price')
instance.publish_id = validated_data.get('publish')
#作者 先清空 在添加
books2author = validated_data.get('author')
instance.books2author.clear()
instance.books2author.add(*books2author)
instance.save()
return instance
反序列化字段校验流程
1.字段自己的 name = serializers.CharField(max_length=8, error_messages={'max_length': '太长了'})
2.validators = [方法,]
3.局部钩子
4.全局钩子
ModelSerializer使用
ModelSerializer继承Serializer
跟表模型强关联
大部分请求不用写create和update
serializer.py
class BookSerializer(serializers.ModelSerializer):
#跟表有关联
class Meta:
model = Books #跟book表建立了关系 序列化类跟表模型类建了关系
# fields = '__all__' #
fields = ['name','price','publish_dict','author_list','publish','books2author'] #序列化所有name和price字段你
#方式一:定制name反序列化时 最长不能超过8 给字段加属性
extra_kwargs={'name': {'max_length': 8},
'publish':{"write_only":True},
'books2author':{"write_only":True},
}
#方式二:定制name反序列化的时候最长不能超过8 给字段加属性 重写name字段
#当 里面有fields = '__all__' 外面也定制了 先执行外面的
# # name= serializers.CharField(max_length=8)
#
# #所有的read_only和write_only都可以重写或者使用extra_kwargs传入
# publish_dict = serializers.SerializerMethodField(read_only=True)
# def get_publish_dict(self,obj):
# return {'name':obj.publish.name,'add':obj.publish.add}
#
# author_list = serializers.SerializerMethodField(read_only=True)
# def get_author_list(self,obj):
# l = []
# for author in obj.books2author.all():
# l.append({'name':author.name,'phone':author.phone})
# return l
# 局部钩子和全局钩子跟之前完全一样
def validate_name(self, name):
if name.startswith('sb'):
raise ValidationError('不能sb')
else:
return name