DRF源码-fields.py
https://www.cnblogs.com/pyspark/p/8607801.html
https://www.cnblogs.com/LYliangying/articles/9896548.html
fieids.py主要定义了各种字段的序列化类。Field是基类。
class Field
_creation_counter = 0
default_error_messages = {
'required': _('This field is required.'),
'null': _('This field may not be null.')
}
default_validators = [] #默认验证器初始化为空list
default_empty_html = empty
initial = None
# 在构造函数中,给出了各种定义参数,由子类继承,在实例化时传参,来控制这个字段的各种属性
# read_only,表明只用于序列化输出
# write_only, 表明只用于反序列化输入,比如密码
# required, 表明在反序列化时必须输入
# default, 反序列化时使用的默认值
# initial
# source,
# label, 用于HTML展示API页面时,显示的字段名称
# help_text, 用于HTML展示API页面时,显示的字段帮助提示信息
# style
# error_messages, 包含错误编号与错误信息的字典
# validators, 该字段使用的验证器
# allow_null, 表明该字段是否允许传入None,默认False
def __init__(self, read_only=False, write_only=False,
required=None, default=empty, initial=empty, source=None,
label=None, help_text=None, style=None,
error_messages=None, validators=None, allow_null=False):
self._creation_counter = Field._creation_counter
Field._creation_counter += 1 # If `required` is unset, then use `True` unless a default is provided.
if required is None:
required = default is empty and not read_only # Some combinations of keyword arguments do not make sense.
# 断言一些没有意义的参数组合
assert not (read_only and write_only), NOT_READ_ONLY_WRITE_ONLY
assert not (read_only and required), NOT_READ_ONLY_REQUIRED
assert not (required and default is not empty), NOT_REQUIRED_DEFAULT
assert not (read_only and self.__class__ == Field), USE_READONLYFIELD # 将传入的参数赋值给实例(属性初始化)
self.read_only = read_only
self.write_only = write_only
self.required = required
self.default = default
self.source = source
self.initial = self.initial if (initial is empty) else initial
self.label = label
self.help_text = help_text
self.style = {} if style is None else style
self.allow_null = allow_null if self.default_empty_html is not empty:
if default is not empty:
self.default_empty_html = default if validators is not None:
self.validators = list(validators) # These are set up by `.bind()` when the field is added to a serializer.
self.field_name = None
self.parent = None # Collect default error message from self and parent classes
messages = {}
for cls in reversed(self.__class__.__mro__):
messages.update(getattr(cls, 'default_error_messages', {}))
messages.update(error_messages or {})
self.error_messages = messages
# .validators is a lazily loaded property, that gets its default
# value from `get_validators`.
# validators属性设置
@property
def validators(self):
if not hasattr(self, '_validators'):
self._validators = self.get_validators()
return self._validators @validators.setter
def validators(self, validators):
self._validators = validators def get_validators(self):
return list(self.default_validators)
子类
class IntegerField(Field):
default_error_messages = {
'invalid': _('A valid integer is required.'),
'max_value': _('Ensure this value is less than or equal to {max_value}.'),
'min_value': _('Ensure this value is greater than or equal to {min_value}.'),
'max_string_length': _('String value too large.')
}
MAX_STRING_LENGTH = 1000 # Guard against malicious string inputs.
re_decimal = re.compile(r'\.0*\s*$') # allow e.g. '1.0' as an int, but not '1.2' def __init__(self, **kwargs):
# 从变长传参里找max_value,min_value,给到实例,默认为None
#继承父类的其他属性(相当于父类属性是通用,这里的属性是子类独有的)
self.max_value = kwargs.pop('max_value', None)
self.min_value = kwargs.pop('min_value', None)
super().__init__(**kwargs)
# 如果传参max_value,先拼接error message,然后在validators属性里添加一个验证器元素。
if self.max_value is not None:
message = lazy_format(self.error_messages['max_value'], max_value=self.max_value)
self.validators.append(
MaxValueValidator(self.max_value, message=message))
if self.min_value is not None:
message = lazy_format(self.error_messages['min_value'], min_value=self.min_value)
self.validators.append(
MinValueValidator(self.min_value, message=message)) def to_internal_value(self, data):
if isinstance(data, str) and len(data) > self.MAX_STRING_LENGTH:
self.fail('max_string_length') try:
data = int(self.re_decimal.sub('', str(data)))
except (ValueError, TypeError):
self.fail('invalid')
return data def to_representation(self, value):
return int(value)
class CharField(Field):
default_error_messages = {
'invalid': _('Not a valid string.'),
'blank': _('This field may not be blank.'),
'max_length': _('Ensure this field has no more than {max_length} characters.'),
'min_length': _('Ensure this field has at least {min_length} characters.'),
}
initial = '' def __init__(self, **kwargs):
self.allow_blank = kwargs.pop('allow_blank', False)
self.trim_whitespace = kwargs.pop('trim_whitespace', True)
self.max_length = kwargs.pop('max_length', None)
self.min_length = kwargs.pop('min_length', None)
super().__init__(**kwargs)
if self.max_length is not None:
message = lazy_format(self.error_messages['max_length'], max_length=self.max_length)
self.validators.append(
MaxLengthValidator(self.max_length, message=message))
if self.min_length is not None:
message = lazy_format(self.error_messages['min_length'], min_length=self.min_length)
self.validators.append(
MinLengthValidator(self.min_length, message=message)) # ProhibitNullCharactersValidator is None on Django < 2.0
if ProhibitNullCharactersValidator is not None:
self.validators.append(ProhibitNullCharactersValidator()) def run_validation(self, data=empty):
# Test for the empty string here so that it does not get validated,
# and so that subclasses do not need to handle it explicitly
# inside the `to_internal_value()` method.
if data == '' or (self.trim_whitespace and str(data).strip() == ''):
if not self.allow_blank:
self.fail('blank')
return ''
return super().run_validation(data) # 将int,float转为为str
def to_internal_value(self, data):
# We're lenient with allowing basic numerics to be coerced into strings,
# but other types should fail. Eg. unclear if booleans should represent as `true` or `True`,
# and composites such as lists are likely user error.
if isinstance(data, bool) or not isinstance(data, (str, int, float,)):
self.fail('invalid')
value = str(data)
return value.strip() if self.trim_whitespace else value def to_representation(self, value):
return str(value)
DRF源码-fields.py的更多相关文章
- DRF源码-views.py
REST框架提供了一个APIView类,它是Django View类的子类. 要了解几个特点: 请求中body中的数据全部都封装到了data中(原POST,PUT,PATCH,DELETE中的数据全部 ...
- Django之DRF源码分析(二)---数据校验部分
Django之DRF源码分析(二)---数据校验部分 is_valid() 源码 def is_valid(self, raise_exception=False): assert not hasat ...
- 02 drf源码剖析之快速了解drf
02 drf源码剖析之快速了解drf 目录 02 drf源码剖析之快速了解drf 1. 什么是drf 2. 安装 3. 使用 3. DRF的应用场景 1. 什么是drf drf是一个基于django开 ...
- Django与drf 源码视图解析
0902自我总结 Django 与drf 源码视图解析 一.原生Django CBV 源码分析:View """ 1)as_view()是入口,得到view函数地址 2) ...
- drf源码save以及response
drf源码save以及response 一.save 其中蛮重要的一段 if self.instance is not None: self.instance = self.update(self.i ...
- DRF源码系列分析
DRF源码系列分析 DRF源码系列分析--版本 DRF源码系列分析--认证 DRF源码系列分析--权限 DRF源码系列分析--节流
- [drf]源码和序列化梳理
drf源码继承管理 # drf继承关系 View APIView as_view: 执行父类的as_view 调用dispatch dispatch init_request request.quer ...
- drf源码剖析系列(系列目录)
drf源码剖析系列(系列目录) 01 drf源码剖析之restful规范 02 drf源码剖析之快速了解drf 03 drf源码剖析之视图 04 drf源码剖析之版本 05 drf源码剖析之认证 06 ...
- 07 drf源码剖析之节流
07 drf源码剖析之节流 目录 07 drf源码剖析之节流 1. 节流简述 2. 节流使用 3. 源码剖析 总结: 1. 节流简述 节流类似于权限,它确定是否应授权请求.节流指示临时状态,并用于控制 ...
随机推荐
- 标准模板库中的优先队列(priority_queue)
//C++数据结构与算法(第4版) Adam Drozdek 著 徐丹 吴伟敏<<清华大学出版社>> #include<queue> priority_queu ...
- luogu P2763 试题库问题
本题可以用最大流也可以用最大匹配(本质一样),用dinic最大流好建图,但码量大,匈牙利码量小,建图费点劲. 最大流:依旧是设一个源点一个汇点,对于每一个种类,连一条到汇点的边,capacity为需要 ...
- 条形码识别手持终端(PDA)人们每日触碰的科技
时尚达人的你,收快递物流时,毫无疑问在有时会好奇心,派送员腰部取出的那把“扫枪”,轻轻地一扫后,给你打开享有开拆快递物流的开心時刻.老湿机的你,是否会突然发觉,泊车交费时收费员哥哥已不找你许多零钱,只 ...
- ajax请求QQ音乐
搜索歌曲 function go() { var val = document.getElementById("name").value; ...
- Html5使用audio播放音乐
html代码 <audio id="myaudio" src="http://ws.stream.qqmusic.qq.com/C100003R74Cn0JR4O ...
- springboot中文官方文档
springboot中文官方文档 https://www.breakyizhan.com/springboot/3028.html spring框架 https://www.breakyizhan.c ...
- Golang函数-递归函数
Golang函数-递归函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- Zabbix——自动监控
zabbix简介 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管 ...
- RAID与磁盘管理之——综合应用
为了实现磁盘的管理和RAID的综合,现将四块硬盘组合成一个RAID10,并在此基础之上创建物理卷.卷组.逻辑卷,实现在线扩容,最后挂载使用. 其中也部分包含了swap分区的创建和使用. 1.根据lin ...
- 冰蝎动态二进制加密WebShell基于流量侧检测方案
概述 冰蝎是一款新型动态二进制加密网站工具.目前已经有6个版本.对于webshell的网络流量侧检测,主要有三个思路.一:webshell上传过程中文件还原进行样本分析,检测静态文件是否报毒.二:we ...