目录
1 序列化类常用字段和字段参数
1.1 常用字段类
字段 | 字段构造方式 |
---|---|
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(maxlength=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) |
ListField | ListField(child=, min_length=None, max_length=None) |
DictField | DictField(child=) |
选项参数:
参数名称 | 作用 |
---|---|
max_length | 最大长度 |
min_lenght | 最小长度 |
allow_blank | 是否允许为空 |
trim_whitespace | 是否截断空白字符 |
max_value | 最小值 |
min_value | 最大值 |
通用参数:
参数名称 | 说明 |
---|---|
read_only | 表明该字段仅用于序列化输出,默认False |
write_only | 表明该字段仅用于反序列化输入,默认False |
required | 表明该字段在反序列化时必须输入,默认True |
default | 反序列化时使用的默认值 |
allow_null | 表明该字段是否允许传入None,默认False |
validators | 该字段使用的验证器 |
error_messages | 包含错误编号与错误信息的字典 |
label | 用于HTML展示API页面时,显示的字段名称 |
help_text | 用于HTML展示API页面时,显示的字段帮助提示信息 |
1.2反序列化校验执行流程
-1 先执行字段自己的校验规则----》最大长度,最小长度,是否为空,是否必填,最小数字。。。。
-2 validators=[方法,] ----》单独给这个字段加校验规则
name=serializers.CharField(validators=[方法,])
-3 局部钩子校验规则
-4 全局钩子校验规则
2 序列化高级用法之source
from django.db import models
# Create your models here.
class Book(models.Model):
name=models.CharField(max_length=32)
price=models.CharField(max_length=32)
publish=models.ForeignKey(to='Publish',on_delete=models.CASCADE)
authors=models.ManyToManyField(to='Author')
def __str__(self):
return self.name
class Publish(models.Model):
name=models.CharField(max_length=32)
addr=models.CharField(max_length=32)
def __str__(self):
return self.name
class Author(models.Model):
name = models.CharField(max_length=32)
phone=models.CharField(max_length=11)
def __str__(self):
return self.name
2.1 序列化定制字段名字
from rest_framework import serializers
class BookSerializer(serializers.Serializer):
#字段参数通用,所有字段都可以写source
#自由字段,直接写名字
name_dateil=serializers.CharField(max_length=8,source='name')
price=serializers.CharField()
#关联字段直接点外键
publish=serializers.CharField(source='publish.name')
#多对多,不建议用source
author=serializers.CharField(source='authors.all')
3 序列化高级用法之定制字段的两种方式
3.1 SerializerMethodField定制
from rest_framework import serializers
class BookSerializer(serializers.Serializer):
name=serializers.CharField(max_length=8)
price=serializers.CharField()
publish_detail=serializers.SerializerMethodField()
def get_publish_detail(self,obj):
return {'name':obj.publish.name,'addr':obj.publish.addr}
author_list=serializers.SerializerMethodField()
def get_author_list(self,obj):
list=[]
for author in obj.authors.all():
list.append({'name':author.name,'phone':author.phone})
return list
运行结果
[{"name":"富婆通讯录","price":"22","publish_detail":{"name":"北京出版社","addr":"北京"},"author_list":[{"name":"阿红","phone":"22222"},{"name":"阿红","phone":"1233"}]},{"name":"甜妹合集","price":"33","publish_detail":{"name":"日本出版社","addr":"日本"},"author_list":[{"name":"阿红","phone":"22222"}]}]
3.2 在表模型中定制
# models
class Book(models.Model):
name=models.CharField(max_length=32)
price=models.CharField(max_length=32)
publish=models.ForeignKey(to='Publish',on_delete=models.CASCADE)
authors=models.ManyToManyField(to='Author')
def __str__(self):
return self.name
def publish_detail(self):
return {'name': self.publish.name, 'addr': self.publish.addr}
def author_list(self):
list = []
for author in self.authors.all():
list.append({'name': author.name, 'phone': author.phone})
return list
# serializer
class BookSerializer(serializers.Serializer)
name=serializers.CharField(max_length=8)
price=serializers.CharField()
publish_detail=serializers.DictField()
author_list=serializers.ListField()
运行结果
[{"name":"富婆通讯录","price":"22","publish_detail":{"name":"北京出版社","addr":"北京"},"author_list":[{"name":"阿红","phone":"22222"},{"name":"阿红","phone":"1233"}]},{"name":"甜妹合集","price":"33","publish_detail":{"name":"日本出版社","addr":"日本"},"author_list":[{"name":"阿红","phone":"22222"}]}]
4 多表关联反序列化保存
4.1 新增图书接口
# 新增图书接口
-前端传入的数据格式:{name:红楼梦,price:19,publish:1,authors:[1,2]}
# views
class BookView(APIView):
def post(self,request):
ser=BookSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code':100,'msg':ser.data})
else:
return Response({'code':101,'msg':ser.errors})
# serializer
class BookSerializer(serializers.Serializer):
# name和price 既用来序列化,又用来反序列化 即写又读 ,不用加read_only,write_only
name = serializers.CharField(max_length=8)
price = serializers.CharField()
# 只用来做序列化 只读 read_only
publish_detail = serializers.DictField(read_only=True)
author_list = serializers.ListField(read_only=True)
# 只用来做反序列化 只写 write_only
publish = serializers.CharField(write_only=True)
authors = serializers.ListField(write_only=True)
def create(self, validated_data):
book = Book.objects.create(
name=validated_data.get('name'),
price=validated_data.get('price'),
publish_id=validated_data.get('publish')
)
book.authors.add(*validated_data.get('authors'))
return book
运行结果
{"code":100,"msg":{"name":"红楼梦","price":"19","publish_detail":{"name":"北京出版社","addr":"北京"},"author_list":[{"name":"阿红","phone":"22222"},{"name":"阿红","phone":"1233"}]}}
4.2 修改图书接口
# 新增图书接口
-前端传入的数据格式:{name:红楼梦,price:19,publish:1,authors:[1,2]}
# views
class BookDetailView(APIView):
def get(self,request,pk):
books=Book.objects.filter(pk=pk).first()
ser=BookSerializer(instance=books)
return Response(ser.data)
def put(self,request,pk):
book=Book.objects.filter(pk=pk).first()
ser=BookSerializer(instance=book,data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': ser.data})
else:
return Response({'code': 101, 'msg': ser.errors})
# serializer
class BookSerializer(serializers.Serializer):
# name和price 既用来序列化,又用来反序列化 即写又读 ,不用加read_only,write_only
name = serializers.CharField(max_length=8)
price = serializers.CharField()
# 只用来做序列化 只读 read_only
publish_detail = serializers.DictField(read_only=True)
author_list = serializers.ListField(read_only=True)
# 只用来做反序列化 只写 write_only
publish = serializers.CharField(write_only=True)
authors = serializers.ListField(write_only=True)
def create(self, validated_data):
book = Book.objects.create(
name=validated_data.get('name'),
price=validated_data.get('price'),
publish_id=validated_data.get('publish')
)
book.authors.add(*validated_data.get('authors'))
return book
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')
authors=validated_data.get('authors')
instance.authors.clear()
instance.authors.add(*authors)
instance.save()
return instance
5 反序列化字段校验其他
# 4层
-1 字段自己的:举例:name = serializers.CharField(max_length=8, error_messages={'max_length': '太长了'})
-2 validators=[方法,] 忽略掉
-3 局部钩子
-4 全局钩子
6 ModelSerializer使用
# ModelSerializer 继承自Serializer,完成了很多操作
-跟表模型强关联
-大部分请求,不用写create和update了
### ModelSerializer的使用
# views 不用动
# serializer
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
# fields='__all__'
fields = ['name', 'price', 'publish_detail', 'author_list', 'publish', 'authors']
extra_kwargs = {'name': {'max_length': 8},
'publish_detail':{'read_only':True},
'author_list':{'read_only':True},
'publish':{'write_only':True},
'authors':{'write_only':True},
}
#方式1在serializer定制
# publish_detail=serializers.SerializerMethodField()
# def get_publish_detail(self,obj):
# return {'name':obj.publish.name,'addr':obj.publish.addr}
# author_list=serializers.SerializerMethodField()
# def get_author_list(self,obj):
# list=[]
# for author in obj.authors.all():
# list.append({'name':author.name,'phone':author.phone})
# return list
def validate_name(self, name):
if name.startswith('11'):
raise ValidationError('不能以11开头')
else:
return name
# modes
#方式2在modes定制
class Book(models.Model):
name=models.CharField(max_length=32)
price=models.CharField(max_length=32)
publish=models.ForeignKey(to='Publish',on_delete=models.CASCADE)
authors=models.ManyToManyField(to='Author')
def __str__(self):
return self.name
def publish_detail(self):
return {'name': self.publish.name, 'addr': self.publish.addr}
def author_list(self):
list = []
for author in self.authors.all():
list.append({'name': author.name, 'phone': author.phone})
return list
标签:serializers,name,max,publish,用法,length,多表,序列化
From: https://www.cnblogs.com/bnmm/p/17086775.html