9.27内容整理和概述
今日内容概要
内容目录
- drf序列化类常用字段类
- drf序列化类常用字段参数
- 序列化类之source参数
- 序列化类之定制序列化字段
- ModelSerializer序列化
- 反序列化之数据校验
- 断言assert
drf序列化类常用字段类
高频率:
1.CharField:字符类型 # 例子:变量 = serializers.CharField()
2.IntegerField:整数类型 # 例子:变量 = serializers.IntegerField()
3.1 FloatField:浮点数类型 # 例子:变量 = serializers.FloatField()
3.2 DecimalField:浮点数类型 # 例子:变量 = serializers.DecimalField()
4.ListField:列表类型
5.DictField:字典类型
普通频率:
1.BooleanField:布尔类型 # 例子:变量 = serializers.BooleanField()
2.NullBooleanField:布尔类型(可以为空) # 例子:变量 = serializers.NullBooleanField()
3.EmailField:存放邮箱 # 例子:变量 = serializers.EmailField()
4.1 RegexField:存放正则 # 例子:变量 = serializers.RegexField()
4.2 SlugField:存放正则 # 例子:变量 = serializers.SlugField()
5. URLField:存放url地址 # 例子:变量 = serializers.URLField()
6.UUIDField:存放特殊类型字符串(例子:5ce0e9a5-5ffa-654b-cee0) # 没用过,没有栗子举
7.IPAddressField:存放ip地址 # 有非常规参数
8.1 DateTimeField:时间类型 # 有非常规参数
8.2 DateField:时间类型 # 有非常规参数
8.3 TimeField:时间类型 # 有非常规参数
8.4 DurationField:时间类型
9.1 ChoiceField:单选
9.2 MultipleChoiceField:多选
10.FileField:文件类型 # 例子:变量 = FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
11.ImageField:图片类型 # 例子:变量 = serializers.ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
drf序列化类常用字段参数
功能:用于反序列化校验参数
选项参数: # 指定类的专属参数
1.CharField类参数:
1.max_length:最大长度
2.min_lenght:最小长度
3.allow_blank:是否允许为空
4.trim_whitespace:是否截断空白字符
2.IntegerField类参数:
1.max_value:最小值
2.min_value:最大值
通用参数:
1.required:表明该字段在反序列化时必须输入(必填) # 默认True
2.default:反序列化时使用的默认值
3.allow_null:表明该字段是否允许传入None # 默认False
4.validators:该字段使用的验证器(第二层校验) # 不需要了解,也不需要用
5.error_messages:包含错误编号与错误信息 # 字典类型
6.label:用于HTML展示API页面时,显示的字段名称 # 不重要
7.help_text:用于HTML展示API页面时,显示的字段帮助提示信息 # 不重要
'------重点------'
8.read_only:表明该字段仅用于序列化输出 # 默认False
9.write_only:表明该字段仅用于反序列化输入 # 默认False
序列化类之source参数
功能:绑定序列化类字段与model类字段的对应关系,从而实现改字段名操作
例子:book_name = serializers.CharField(max_length=8, min_length=3,source='name')
功能:绑定book类的name字段,并且发送数据时字段名为book_name
# 补充:source参数名不能和该字段名相同,不然报错
source参数范围:
1.model类字段
2.model类方法
3.可以通过对象进行跨表绑定 # 例子:source='对象.字段'
序列化类之定制序列化字段
'--------------第一种---------------'
基于SerializerMethodField方法定制: # 例子:字段名 = serializers.SerializerMethodField()
前提:必须配合一个'get_字段名'的方法,且有参数(self,obj) # obj:当前被序列化的对象
功能:此方法返回什么该字段便是什么数据
例子:
class BookSerializer(serializers.Serializer): # 当前路径:serializer.py
publish = serializers.SerializerMethodField()
def get_publish(self, obj):
return {'name': obj.publish.name, 'city': obj.publish.city, 'email': obj.publish.email}
'--------------第二种---------------'
基于model表模型方法定制: # 架构师:领域驱动模型(ddd)
原理:类似序列化model表字段去序列化model表方法
步骤:
1.先在models表中定义方法,规定返回的数据
2.在serializer表中,直接序列此方法
例子:
class Book(models.Model):
def publish_detail(self): # 当前路径:models.py
return {'name': self.publish.name, 'city': self.publish.city, 'email': self.publish.email}
publish_detail=serializers.DictField() # # 当前路径:serializer.py
ModelSerializer序列化
应用背景:传统的serializers.Serializer类做数据的序列化,太过冗长,为了简便效率,用Serializer的子类:ModelSerializer
Serializer的缺点:
1.无论是序列化还是反序列化,每个字段都要写
2.如果新增或者修改,在序列化类中都需要重写create或update
步骤:
1.定义一个序列化类继承serializers.ModelSerializer
2.类内部写必须写内部类Meta类
3.在内部类中指定model(要序列化的表) # 例子:model = Book
4.在内部类中指定fields # fields属性指定序列化和反序列化的字段
5.在extra_kwargs参数中添加字段参数
6.支持在ModelSerializer优先使用重写字段
7.不需要重写create和update # 也可以重写,如果重写优先使用自己重写的
例子:
class BookModelSerializer(serializers.ModelSerializer):
name = serializers.SerializerMethodField() # 重写字段
def get_name(self, obj):
return 'sb---' + obj.name
class Meta: # Meta类必写
model = Book # model属性指定被序列化的表模型
fields = ['name', 'price', 'publish_date', 'publish', 'authors', 'publish_detail',
'author_list'] # fields属性指定序列化和反序列化的字段。当fields='__all__'时,指所有字段都序列化
extra_kwargs = { # extra_kwargs给字段增加参数
'name': {'max_length': 8},
'publish': {'write_only': True},
'authors': {'write_only': True},
}
'--------------基于SerializerMethodField方法定制字段做反序列化---------------'
publish_detail = serializers.SerializerMethodField(read_only=True) #
...
author_list = serializers.SerializerMethodField(read_only=True)
...
'--------------基于基于model表模型方法字段做反序列化---------------'
直接将model表的方法字段名写在fields参数里
反序列化之数据校验
三层数据校验:
第一层————字段的校验规则
第二层————局部钩子校验: # Serializer类和ModelSerializer类写法一样
步骤:
1.定义'validate_字段名'方法
2.方法参数为(self, 字段)
3.编写校验逻辑
4.校验不通过,抛异常 # ValidationError
5.校验通过将字段返回出去
例子:
def validate_name(self, name):
if name.startswith('sb'):
raise ValidationError('不能以sb卡头')
else:
return name
第三层————全局钩子校验:
步骤:
1.定义'validate'方法
2.方法参数为(self, 全部数据)
3.编写校验逻辑
4.校验不通过,抛异常 # ValidationError
5.校验通过将全部数据返回出去
例子:
def validate(self, attrs):
if attrs.get('name') == attrs.get('publish_date'):
raise ValidationError('名字不能等于日期')
else:
return attrs
执行顺序:字段的校验规则-->局部钩子校验-->全局钩子校验 # 顺序:一二三
'------------源码分析---------------'
1.视图类中检验数据调用'数据对象.is_valid()'
2.is_valid方法在BaseSerializer类中,真正的作用就是调用Serializer类中的run_validation方法
# 源码:self._validated_data = self.run_validation(self.initial_data)
3.run_validation方法主要功能:
1.执行to_internal_value方法,进行字段检验和局部钩子 # 源码:value = self.to_internal_value(data)
2.当两者都通过时,执行全局钩子 # 源码:value = self.validate(value)
4.to_internal_value方法主要步骤:
1.循环序列化类中所有的字段 # 源码:for field in fields:
2.每次循环通过反射拿取局部钩子的地址 # 源码:validate_method = getattr(self, 'validate_' + field.field_name, None)
3.然后进行字段检验 # 源码:validated_value = field.run_validation(primitive_value)
4.如果局部钩子存在,进行局部钩子检验 # 源码:if validate_method is not None: validated_value = validate_method(validated_value)
5.如果字段检验不合格,第一次循环就立即结束报错,所以检验执行顺序:字段的校验规则-->局部钩子校验
补充:自己写的序列化类---》继承了ModelSerializer---》继承了Serializer---》BaseSerializer---》Field
断言assert
功能:断定一个变量必须是xx,如果不是就报错
例子:
name = 'lqz1'
assert name == 'lqz', 'name不等于lqz'
print('程序执行完了')
解释:
1.如果name为lqz,执行下面的程序
2.如果name不为lqz,抛异常,报错信息为'name不等于lqz'